#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk-2.0/gtk/gtk.h>
#include <mysql/mysql.h>
#include <regex.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
Go to the source code of this file.
Defines | |
#define | BUFFER 1024 |
Server.c. | |
#define | PORT_NUMBER 9999 |
#define | MAX_MARKS 800 |
#define | MIN_MARKS 200 |
#define | STARTING_MARKS 400 |
#define | TOTAL_QUESTION 10 |
#define | TOTAL_TIME 1 |
Functions | |
void | Bind (int sockfd, const struct sockaddr *my_addr, socklen_t addrlen) |
bind implementation with error handling. | |
void | Listen (int sockfd, int backlog) |
Listen implementation with error handling. | |
int | Socket (int domain, int type, int protocol) |
Socket function reimplementation with error handling . | |
ssize_t | Read (int fd, void *buf, size_t count) |
Read function reimplementation with error handling . | |
ssize_t | Write (int fd, const void *buf, size_t count) |
write function reimplementation with error handling . | |
void | Close (int fd) |
Close function reimplementation with error handling. | |
int | Accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen) |
accept function reimplementaion with error handling. | |
int | Open (const char *pathname, int flags) |
to open a file | |
void | Fstat (int filedes, struct stat *buf) |
to check the status of the file | |
int | connect_database () |
Used to connect to the mysql database and set the connection1 global variable. | |
int | search (int *pool, int qno, int len) |
Used to check that a question in the pool already asked question. | |
int | verify_user (char *username, char *password) |
Used to verify the user name and passwrod. | |
void | handle_client_thread (void *sockfd) |
This is the thread that is created each time a client connects to take the test. | |
int | main () |
Main function declares all variables and accepts connections from the clients and assign them a thread with a connection file descriptor describing their connection. | |
Variables | |
MYSQL * | connection1 |
mysql connection parameter global | |
MYSQL * | connection2 |
MYSQL_RES * | result |
mysql result parameter global | |
MYSQL_ROW | sqlrow |
mysql row parameter global | |
char | sql_statement [BUFFER] |
Global Variable storing the sql statement to be executed which is set by the thread in execution. | |
char | ack [10] |
to store a string ACK to acknowledge the receipt of input from socket | |
int | data_file_descriptor |
data file descripter for image file | |
struct stat | file_status |
file status | |
char | student_id [BUFFER] |
student_id |
#define STARTING_MARKS 400 |
Definition at line 28 of file server.c.
Referenced by handle_client_thread().
#define TOTAL_QUESTION 10 |
Definition at line 29 of file server.c.
Referenced by handle_client_thread().
#define TOTAL_TIME 1 |
Definition at line 30 of file server.c.
Referenced by handle_client_thread().
int Accept | ( | int | sockfd, | |
struct sockaddr * | addr, | |||
socklen_t * | addrlen | |||
) |
accept function reimplementaion with error handling.
Definition at line 153 of file server.c.
References Close().
Referenced by main().
00153 { 00154 int file_descriptor; 00155 file_descriptor = accept(sockfd, addr, addrlen); 00156 if (file_descriptor < 0) { 00157 perror("accept() failed."); 00158 Close(sockfd); 00159 00160 } 00161 return file_descriptor; 00162 }
void Bind | ( | int | sockfd, | |
const struct sockaddr * | my_addr, | |||
socklen_t | addrlen | |||
) |
void Close | ( | int | fd | ) |
Close function reimplementation with error handling.
fd | filedescriptor to close |
int connect_database | ( | ) |
Used to connect to the mysql database and set the connection1 global variable.
Definition at line 201 of file server.c.
References connection1.
Referenced by handle_client_thread().
00201 { 00202 /* connect to mysql database */ 00203 connection1 = mysql_init(NULL); 00204 if (!connection1) { 00205 fprintf(stderr, "MySQL initialization failed\n"); 00206 return -1; 00207 } 00208 if (mysql_real_connect(connection1, "localhost", "naru", "naru", "onlineexam", 0, NULL, 0)) { 00209 return 1; 00210 } else { 00211 fprintf(stderr, "Connection failed\n"); 00212 if (mysql_errno(connection1)) { 00213 fprintf(stderr, "Connection error %d: %s\n", 00214 mysql_errno(connection1), 00215 mysql_error(connection1)); 00216 } 00217 mysql_close(connection1); 00218 return -1; 00219 } 00220 }
void Fstat | ( | int | filedes, | |
struct stat * | buf | |||
) |
to check the status of the file
filedes | file_descriptor | |
buf | to store the status of the file |
Definition at line 186 of file server.c.
Referenced by handle_client_thread().
void handle_client_thread | ( | void * | sockfd | ) |
This is the thread that is created each time a client connects to take the test.
It is responsible for all the test question selection and adaptive test algorithm for selecting criteria.
sockfd | connection descriptor of the client. |
Definition at line 288 of file server.c.
References ack, answer, BUFFER, characters_read, Close(), connect_database(), connection1, current_question, data_file_descriptor, file_status, Fstat(), input_data, login_status, marks, Open(), password, Read(), result, search(), sql_statement, sqlrow, STARTING_MARKS, student_id, TOTAL_QUESTION, TOTAL_TIME, username, verify_user(), and Write().
Referenced by main().
00288 { 00289 00290 int connection_file_descriptor = *((int *) sockfd); 00291 int characters_read; 00292 int ret; 00293 int flag; 00294 00295 00296 int count_tuples; 00297 int random_qno; 00298 char temp_table[BUFFER]; 00299 00300 char question_imageurl[BUFFER]; 00301 char question_statement[BUFFER]; 00302 char question_optiona[BUFFER]; 00303 char question_optionb[BUFFER]; 00304 char question_optionc[BUFFER]; 00305 char question_optiond[BUFFER]; 00306 00307 /* other global parameter */ 00308 char username[BUFFER]; 00309 char password[BUFFER]; 00310 char answer[BUFFER]; 00311 char question_answer[BUFFER]; 00312 char input_data[BUFFER]; 00313 char login_status[10]; 00314 int current_question; 00315 int marks; 00316 00317 00318 int *poola; 00319 int *poolb; 00320 int *poolc; 00321 int *poold; 00322 00323 int ai,af; 00324 int bi,bf; 00325 int ci,cf; 00326 int di,df; 00327 00328 flag = 0; 00329 marks = STARTING_MARKS; 00330 current_question = 1; 00331 ai=0; 00332 bi=0; 00333 ci=0; 00334 di=0; 00335 00336 //allocation of the memory to already asked questions from various pools 00337 poola=(int*)malloc(sizeof(int)*TOTAL_QUESTION); 00338 poolb=(int*)malloc(sizeof(int)*TOTAL_QUESTION); 00339 poolc=(int*)malloc(sizeof(int)*TOTAL_QUESTION); 00340 poold=(int*)malloc(sizeof(int)*TOTAL_QUESTION); 00341 00342 00343 00344 if (connect_database() <= 0) { 00345 flag = 1; 00346 } 00347 00348 00349 do { 00350 00351 //username read 00352 characters_read = Read(connection_file_descriptor, username, BUFFER - 1); 00353 00354 username[characters_read] = '\0'; 00355 //write back acknowledgement to client 00356 Write(connection_file_descriptor, ack, strlen(ack)); 00357 00358 00359 //password read 00360 characters_read = Read(connection_file_descriptor, password, BUFFER - 1); 00361 password[characters_read] = '\0'; 00362 //write back acknowledgement to client 00363 Write(connection_file_descriptor, ack, strlen(ack)); 00364 00365 ret = verify_user(username, password); 00366 if (ret == 1 || flag == 1) { 00367 strcpy(login_status, "DBF"); 00368 } else if (ret == 2) { 00369 strcpy(login_status, "UPNM"); 00370 } else { 00371 strcpy(login_status, "OK"); 00372 } 00373 //Read ack ignore 00374 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00375 input_data[characters_read] = '\0'; 00376 00377 //write login status 00378 Write(connection_file_descriptor, login_status, strlen(login_status)); 00379 //Read ack ignore 00380 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00381 input_data[characters_read] = '\0'; 00382 } while (strcmp(login_status, "OK")); 00383 00384 00385 //write total_question 00386 sprintf(input_data, "%d", TOTAL_QUESTION); 00387 Write(connection_file_descriptor, input_data, strlen(input_data)); 00388 //Read ack ignore 00389 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00390 input_data[characters_read] = '\0'; 00391 00392 //write total time 00393 sprintf(input_data, "%d", TOTAL_TIME); 00394 Write(connection_file_descriptor, input_data, strlen(input_data)); 00395 //Read ack ignore 00396 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00397 input_data[characters_read] = '\0'; 00398 00399 for (current_question = 1; current_question <= TOTAL_QUESTION + 1; current_question++) { 00400 //fill Question from mysql 00401 00402 af=0; 00403 bf=0; 00404 cf=0; 00405 df=0; 00406 if (current_question > 1 && current_question <= TOTAL_QUESTION + 1) { 00407 if (!strcmp(answer, question_answer)) { 00408 if (marks >= 900) { 00409 ; 00410 } else { 00411 marks = marks + 50; 00412 } 00413 } else { 00414 if (marks <= 100) { 00415 ; 00416 } else { 00417 marks = marks - 50; 00418 } 00419 00420 } 00421 if (current_question == TOTAL_QUESTION + 1) { 00422 if (marks < 200) { 00423 marks = 200; 00424 } 00425 if (marks > 800) { 00426 marks = 800; 00427 } 00428 00429 } 00430 00431 } 00432 00433 //printf("%d %s %s\n",marks,answer,question_answer); 00434 00435 if (current_question <= TOTAL_QUESTION) { 00436 strcpy(question_imageurl, "NO IMAGE"); 00437 00438 if (marks < 500) { 00439 strcpy(temp_table, "question_poola"); 00440 af=1; 00441 } else if (marks < 600) { 00442 strcpy(temp_table, "question_poolb"); 00443 bf=1; 00444 } else if (marks < 700) { 00445 strcpy(temp_table, "question_poolc"); 00446 cf=1; 00447 } else { 00448 strcpy(temp_table, "question_poold"); 00449 df=1; 00450 } 00451 00452 00453 sprintf(sql_statement, "select q_id from %s", temp_table); 00454 ret = mysql_query(connection1, sql_statement); 00455 result = mysql_store_result(connection1); 00456 count_tuples = mysql_num_rows(result); 00457 mysql_free_result(result); 00458 00459 00460 random_qno = rand() % count_tuples; 00461 while (random_qno <= 0) { 00462 random_qno = rand() % count_tuples; 00463 } 00464 00465 while(1) { 00466 if(af==1) { 00467 if(search(poola,random_qno,ai)==0) { 00468 random_qno=rand()%count_tuples; 00469 while (random_qno <= 0) { 00470 random_qno = rand() % count_tuples; 00471 } 00472 continue; 00473 } else { 00474 poola[ai++]=random_qno; 00475 break; 00476 } 00477 } else if(bf==1) { 00478 if(search(poolb,random_qno,bi)==0) { 00479 random_qno=rand()%count_tuples; 00480 while (random_qno <= 0) { 00481 random_qno = rand() % count_tuples; 00482 } 00483 continue; 00484 } else { 00485 poolb[bi++]=random_qno; 00486 break; 00487 } 00488 } else if(cf==1) 00489 { 00490 if(search(poolc,random_qno,ci)==0) 00491 { 00492 random_qno=rand()%count_tuples; 00493 while (random_qno <= 0) { 00494 random_qno = rand() % count_tuples; 00495 } 00496 continue; 00497 } 00498 else 00499 { 00500 poolc[ci++]=random_qno; 00501 break; 00502 } 00503 } 00504 else 00505 { 00506 if(search(poold,random_qno,di)==0) 00507 { 00508 random_qno=rand()%count_tuples; 00509 while (random_qno <= 0) { 00510 random_qno = rand() % count_tuples; 00511 } 00512 continue; 00513 } 00514 else 00515 { 00516 poold[di++]=random_qno; 00517 break; 00518 } 00519 } 00520 } 00521 00522 00523 sprintf(sql_statement, "select * from %s where q_id= %d", temp_table, random_qno); 00524 ret = mysql_query(connection1, sql_statement); 00525 00526 00527 if (ret) { 00528 printf("select failed as : %s\n", mysql_error(connection1)); 00529 } else { 00530 result = mysql_use_result(connection1); 00531 if (result) { 00532 00533 sqlrow = mysql_fetch_row(result); 00534 if (sqlrow[1] != NULL) { 00535 strcpy(question_imageurl, sqlrow[1]); 00536 } 00537 strcpy(question_statement, sqlrow[2]); 00538 strcpy(question_optiona, sqlrow[3]); 00539 strcpy(question_optionb, sqlrow[4]); 00540 strcpy(question_optionc, sqlrow[5]); 00541 strcpy(question_optiond, sqlrow[6]); 00542 strcpy(question_answer, sqlrow[7]); 00543 if (mysql_errno(connection1)) { 00544 printf("Error occurred while retrieving data : %s\n", mysql_error(connection1)); 00545 } 00546 } 00547 00548 mysql_free_result(result); 00549 } 00550 00551 //Send ImageUrl 00552 Write(connection_file_descriptor, question_imageurl, strlen(question_imageurl)); 00553 //recieve ack it may be timeout check it 00554 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00555 //broken pipe check 00556 if (characters_read <= 0) { 00557 Close(connection_file_descriptor); 00558 pthread_exit(0); 00559 return; 00560 } 00561 00562 input_data[characters_read] = '\0'; 00563 00564 if(!strcmp(input_data,"Timeout")) 00565 { 00566 break; 00567 } 00568 //if there is an image url 00569 if(strcmp(question_imageurl,"NO IMAGE")) 00570 { 00571 00572 data_file_descriptor = Open(question_imageurl, O_RDONLY); 00573 if(data_file_descriptor < 0) 00574 { 00575 printf("Image file can not be opened\n"); 00576 } 00577 else 00578 { 00579 00580 Fstat(data_file_descriptor, &file_status); 00581 00582 characters_read = Read(data_file_descriptor, input_data, BUFFER -1); 00583 while(characters_read > 0) 00584 { 00585 00586 Write(connection_file_descriptor, input_data, characters_read); 00587 characters_read = Read(data_file_descriptor, input_data, BUFFER -1); 00588 } 00589 00590 //recieve ack ignore 00591 characters_read=Read(connection_file_descriptor, input_data, BUFFER - 1); 00592 input_data[characters_read] = '\0'; 00593 Close(data_file_descriptor); 00594 } 00595 00596 } 00597 00598 00599 //Send Question Statement 00600 Write(connection_file_descriptor, question_statement, strlen(question_statement)); 00601 //recieve ack ignore 00602 characters_read=Read(connection_file_descriptor, input_data, BUFFER - 1); 00603 input_data[characters_read] = '\0'; 00604 00605 //Send question_optiona 00606 Write(connection_file_descriptor, question_optiona, strlen(question_optiona)); 00607 //recieve ack ignore 00608 characters_read=Read(connection_file_descriptor, input_data, BUFFER - 1); 00609 input_data[characters_read] = '\0'; 00610 00611 //Send question_optionb 00612 Write(connection_file_descriptor, question_optionb, strlen(question_optionb)); 00613 //recieve ack ignore 00614 characters_read=Read(connection_file_descriptor, input_data, BUFFER - 1); 00615 input_data[characters_read] = '\0'; 00616 00617 //Send question_optionc 00618 Write(connection_file_descriptor, question_optionc, strlen(question_optionc)); 00619 //recieve ack ignore 00620 characters_read=Read(connection_file_descriptor, input_data, BUFFER - 1); 00621 input_data[characters_read] = '\0'; 00622 00623 //Send question_optiond 00624 Write(connection_file_descriptor, question_optiond, strlen(question_optiond)); 00625 //recieve ack ignore 00626 characters_read=Read(connection_file_descriptor, input_data, BUFFER - 1); 00627 input_data[characters_read] = '\0'; 00628 00629 //write back acknowledgement to client 00630 Write(connection_file_descriptor, ack, strlen(ack)); 00631 //recieve answer 00632 characters_read=Read(connection_file_descriptor, answer, BUFFER - 1); 00633 //broken pipe check 00634 if (characters_read <= 0) { 00635 Close(connection_file_descriptor); 00636 pthread_exit(0); 00637 return; 00638 } 00639 answer[characters_read] = '\0'; 00640 00641 00642 00643 //no ack is sent for answer 00644 00645 } 00646 } 00647 00648 //write total marks 00649 00650 sprintf(input_data, "%d", marks); 00651 Write(connection_file_descriptor, input_data, strlen(input_data)); 00652 00653 00654 //Read ack ignore 00655 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00656 input_data[characters_read] = '\0'; 00657 00658 00659 sprintf(sql_statement, "update student_record set student_marks='%d' where student_id='%s'", marks, student_id); 00660 ret = mysql_query(connection1, sql_statement); 00661 00662 00663 if(!strcmp(input_data,"Timeout")) 00664 { 00665 //write total marks 00666 00667 sprintf(input_data, "%d", marks); 00668 Write(connection_file_descriptor, input_data, strlen(input_data)); 00669 00670 sprintf(sql_statement, "update student_record set student_marks='%d' where student_id='%s'", marks, student_id); 00671 ret = mysql_query(connection1, sql_statement); 00672 00673 //Read ack ignore 00674 characters_read = Read(connection_file_descriptor, input_data, BUFFER - 1); 00675 input_data[characters_read] = '\0'; 00676 } 00677 00678 00679 00680 00681 Close(connection_file_descriptor); 00682 pthread_exit(0); 00683 return; 00684 00685 }
void Listen | ( | int | sockfd, | |
int | backlog | |||
) |
int main | ( | ) |
Main function declares all variables and accepts connections from the clients and assign them a thread with a connection file descriptor describing their connection.
Definition at line 692 of file server.c.
References Accept(), ack, Bind(), Close(), handle_client_thread(), Listen(), PORT_NUMBER, and Socket().
00692 { 00693 00694 int connection_file_descriptor, listen_file_descriptor; 00695 int num_clients, i; 00696 struct sockaddr_in server_address; 00697 pthread_t thread[1000]; 00698 00699 listen_file_descriptor = Socket(AF_INET, SOCK_STREAM, 0); 00700 bzero(&server_address, sizeof (server_address)); 00701 server_address.sin_family = AF_INET; 00702 server_address.sin_addr.s_addr = htonl(INADDR_ANY); 00703 server_address.sin_port = htons(PORT_NUMBER); 00704 Bind(listen_file_descriptor, (struct sockaddr *) & server_address, sizeof (server_address)); 00705 Listen(listen_file_descriptor, 1000); 00706 00707 strcpy(ack, "ACK"); 00708 num_clients = 0; 00709 while (1) { 00710 00711 if (num_clients > 999) { 00712 printf("System has reached Maximum Limit:1000 clients"); 00713 break; 00714 } 00715 connection_file_descriptor = Accept(listen_file_descriptor, (struct sockaddr *) NULL, NULL); 00716 00717 //read username after connect success from client 00718 pthread_create(&thread[num_clients], NULL, (void *) & handle_client_thread, (void *) & connection_file_descriptor); 00719 num_clients++; 00720 } 00721 00722 for (i = 0; i <= num_clients; i++) { 00723 pthread_join(thread[i], NULL); 00724 } 00725 00726 Close(listen_file_descriptor); 00727 return 0; 00728 }
int Open | ( | const char * | pathname, | |
int | flags | |||
) |
to open a file
pathname | path of the file | |
flags | read,write etc |
ssize_t Read | ( | int | fd, | |
void * | buf, | |||
size_t | count | |||
) |
Read function reimplementation with error handling .
fd | filedescriptor to read | |
buf | Buffer it is read into | |
count | no of bytes to read. |
Definition at line 113 of file server.c.
References characters_read.
00113 { 00114 ssize_t characters_read; 00115 characters_read = read(fd, buf, count); 00116 return characters_read; 00117 }
int search | ( | int * | pool, | |
int | qno, | |||
int | len | |||
) |
Used to check that a question in the pool already asked question.
pool | pointer to the pool. | |
qno | question number to be searched. |
Definition at line 229 of file server.c.
Referenced by handle_client_thread().
int Socket | ( | int | domain, | |
int | type, | |||
int | protocol | |||
) |
Socket function reimplementation with error handling .
domain | Domain value passed to the socket | |
type | Type of socket.TCP/UDP | |
protocol | protocol of the socket being created. |
int verify_user | ( | char * | username, | |
char * | password | |||
) |
Used to verify the user name and passwrod.
username | Username of the user. | |
password | password of the user. |
Definition at line 249 of file server.c.
References connection1, result, sql_statement, sqlrow, and student_id.
00249 { 00250 int ret; 00251 int flag; 00252 00253 flag = 0; 00254 00255 sprintf(sql_statement, "select * from login_username where uname = '%s'", username); 00256 ret = mysql_query(connection1, sql_statement); 00257 00258 if (ret) { 00259 printf("select failed as : %s\n", mysql_error(connection1)); 00260 flag = 1; 00261 } else { 00262 result = mysql_use_result(connection1); 00263 if (result) { 00264 00265 if ((sqlrow = mysql_fetch_row(result)) && !strcmp(sqlrow[1], password)) { 00266 strcpy(student_id,sqlrow[2]); 00267 } else { 00268 flag = 2; 00269 } 00270 if (mysql_errno(connection1)) { 00271 printf("Error occurred while retrieving data : %s\n", mysql_error(connection1)); 00272 flag = 1; 00273 } 00274 } 00275 mysql_free_result(result); 00276 } 00277 00278 00279 return flag; 00280 }
ssize_t Write | ( | int | fd, | |
const void * | buf, | |||
size_t | count | |||
) |
write function reimplementation with error handling .
fd | filedescriptor to read | |
buf | Buffer it is read into | |
count | no of bytes to read. |
char ack[10] |
MYSQL* connection1 |
mysql connection parameter global
Definition at line 36 of file server.c.
Referenced by connect_database(), handle_client_thread(), and verify_user().
MYSQL * connection2 |
struct stat file_status |
MYSQL_RES* result |
mysql result parameter global
Definition at line 38 of file server.c.
Referenced by handle_client_thread(), and verify_user().
char sql_statement[BUFFER] |
Global Variable storing the sql statement to be executed which is set by the thread in execution.
Definition at line 42 of file server.c.
Referenced by handle_client_thread(), and verify_user().
MYSQL_ROW sqlrow |
mysql row parameter global
Definition at line 40 of file server.c.
Referenced by handle_client_thread(), and verify_user().
char student_id[BUFFER] |
student_id
Definition at line 54 of file server.c.
Referenced by handle_client_thread(), and verify_user().