Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
发送、接收、接收; //获取用户名和密码 recv_ret=recv(新的fd,登录数据,16,0); 如果(recv_ret==0) { 返回-2; } 错误记录(记录,16); //提取用户名和密码 strncpy(用户名,登录名,8); strncp_C_Sockets_Networking_Network Programming_Application Layer - Fatal编程技术网

发送、接收、接收; //获取用户名和密码 recv_ret=recv(新的fd,登录数据,16,0); 如果(recv_ret==0) { 返回-2; } 错误记录(记录,16); //提取用户名和密码 strncpy(用户名,登录名,8); strncp

发送、接收、接收; //获取用户名和密码 recv_ret=recv(新的fd,登录数据,16,0); 如果(recv_ret==0) { 返回-2; } 错误记录(记录,16); //提取用户名和密码 strncpy(用户名,登录名,8); strncp,c,sockets,networking,network-programming,application-layer,C,Sockets,Networking,Network Programming,Application Layer,发送、接收、接收; //获取用户名和密码 recv_ret=recv(新的fd,登录数据,16,0); 如果(recv_ret==0) { 返回-2; } 错误记录(记录,16); //提取用户名和密码 strncpy(用户名,登录名,8); strncpy(密码、登录名+8,8); 用户名[8]=“\0”;密码[8]='\0'; //printf(“用户名(%s)和密码(%s)\n”,用户名,密码); 如果((userId=login(用户名、密码))>0){ //printf(“%d\n”,

发送、接收、接收; //获取用户名和密码 recv_ret=recv(新的fd,登录数据,16,0); 如果(recv_ret==0) { 返回-2; } 错误记录(记录,16); //提取用户名和密码 strncpy(用户名,登录名,8); strncpy(密码、登录名+8,8); 用户名[8]=“\0”;密码[8]='\0'; //printf(“用户名(%s)和密码(%s)\n”,用户名,密码); 如果((userId=login(用户名、密码))>0){ //printf(“%d\n”,userId); //发送状态 strncpy(login\u statsg,login\u OK,2); strncpy(login_statsg+2,totalquesssg,5); send_ret=send(新建fd,登录statMsg,7,0); if(send_ret==0) { 返回-2; } 错误记录(发送报告,7); //TODO错误检查,然后处理错误 //用户[userId][0]=0;//得分 users[userId][1]=new_fd;//与此用户关联的文件描述符 //用户[userId][2]=0;//应答时间 返回1; } 如果(userId=-1){//用户名错误,则为else strncpy(login\u statsg,login\u errowusername,2); strncpy(login_statsg+2,totalquesssg,5); send_ret=send(新建fd,登录statMsg,7,0); if(send_ret==0) { 返回-2; } 错误记录(发送报告,7); 返回0; } 否则{ strncpy(login_statsg,login_error password,2); strncpy(login_statsg+2,totalquesssg,5); send_ret=send(新建fd,登录statMsg,7,0); if(send_ret==0) { 返回-2; } 错误记录(发送报告,7); 返回0; } //上述两种情况的TODO erorr处理 //TODO使登录成为循环 } void*get\u in\u addr(结构sockaddr*sa) { 如果(sa->sa_族==AF_INET){ return&(((struct sockaddr_in*)sa)->sin_addr); } 返回((结构sockaddr_in6*)sa)->sin6_addr); } 内部主(空) { int listen\u fd,new\u fd;//在sock\u fd上侦听,在new\u fd上新建连接 结构addrinfo提示,*servinfo,*p; struct sockaddr\u storage this\u addr;//连接的地址信息 袜子的大小; int yes=1; 字符s[INET6_ADDRSTRLEN]; int-rv; memset(提示和提示,0,提示大小); hints.ai_family=AF_unsec;//IPv4或IPv6 hits.ai_socktype=SOCK_流; hits.ai_flags=ai_PASSIVE;//使用我的IP if((rv=getaddrinfo(NULL,PORT,&hints,&servinfo))!=0){//正在获取IPv服务器支持的内容 fprintf(标准,“getaddrinfo:%s\n”,gai_strerror(rv)); 返回1; } //循环遍历所有结果并绑定到第一个结果 for(p=servinfo;p!=NULL;p=p->ai_next){ if((侦听\u fd=socket(p->ai\u系列,p->ai\u socktype,p->ai\u协议))=-1){ perror(“服务器:套接字”); 继续; } if(setsockopt(listen\u fd,SOL\u SOCKET,SO\u REUSEADDR,&yes,sizeof(int))=-1){ 佩罗尔(“套袜子”); 出口(1); } 如果(绑定(侦听地址,p->ai地址,p->ai地址)=-1){ 关闭(聆听); perror(“服务器:绑定”); 继续; } 打破 } if(p==NULL){ fprintf(stderr,“服务器:绑定失败\n”); 返回2; } freeaddrinfo(servinfo);//所有操作都使用此结构完成 if(监听(监听,待办事项)=-1){ 佩罗尔(“倾听”); 出口(1); } //printf(“listen\u fd(%d)\n”,listen\u fd); //sa.sa_handler=sigchld_handler;//获取所有死进程 //sigemptyset(和sa.sa_面具); //sa.sa_标志=sa_重启; //if(sigaction(SIGCHLD,&sa,NULL)=-1){ //佩罗尔(“sigaction”); //出口(1); // } printf(“正在等待连接的服务器…\n”); fd_set master;//主文件描述符列表 fd_set read_fds;//select()的临时文件描述符列表 int-fdmax; FD_ZERO(&master);//清除主设置和临时设置 FD_零(&read_fds); FD\U设置(监听\U FD和主控); //跟踪bigge文件描述符 fdmax=listen\u fd;//到目前为止是这个 发送接收,发送接收; //用于登录 int loginStatus; struct-sigaction-sa; sa.sa_handler=报警_handler; sigemptyset(和sa.sa_面具); //sa.sa_标志=sa_重启; if(sigaction(SIGALRM,&sa,NULL)=-1){ 佩罗尔(“sigaction”); 出口(1); } //登录时 报警(登录等待);//仅接受登录10秒 定时器=1; printf(“\n--------------------等待用户登录%d秒。------------------------------\n”,登录\u等待); while(计时器){ sin_size=其地址的大小; 新建地址=接受(侦听地址(结构sockaddr*)及其地址和大小); 如果(新的_fd==-1){ //佩罗(“接受”); break;//这个break非常重要,因为我们使用的是报警(信号),accept是一个阻塞函数 //如果accept处于阻塞状态,并且我们的信号出现,则accept将退出返回错误 //如果出现错误,我们必须中断,否则下一个语句将在错误值上运行。 //实际上,我们不需要这个,因为我已经在SIGATION中设置了SAU重启标志,这意味着 //从信号处理程序返回后,请重新启动您以前参与的活动 //而不是从下一行开始执行。 }否则{ inet_ntop(他们的_addr.ss_系列,get_in_addr((struct sockaddr*)和他们的_addr),s,sizeof s); printf(“服务器:已从%s获得连接\n”,s); //LOGIN//需要通过线程调用LOGIN函数,因为 //如果用户没有响应,可能会停止该功能 loginStatus=登录设置(新设置); //添加到选择检查 如果(登录状态){ printf(“用户成功登录\n”); } } } printf(“-------------------------------登录已关闭。现在开始测验----------------
    Define such as:  
    ∆t = (Time Question sent - Time answer received) - RTT  
    Where RTT is Round Trip Time
A. A main while loop which runs once for each question.  
B. Inside this first I am accepting login for 10 seconds.  
       Here I am assigning user Id and all other initialization stuff.  
C. Then using `select` to check which are available for writing.
       To available connections I am checking `RTT` and then sending question to each user.
D. Then I am waiting for some time to get answers.
       Here I am using `select` to determine where the answer is available to read.
E. Then I am repeating steps C. and D.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <error.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>

#define PORT "3490" //the port user will be connecting to
#define BACKLOG 10  //how many pending connection queue will hold
#define maxUser 10
#define LOGIN_OK "OK"
#define LOGIN_WrongPassword "NP"
#define LOGIN_WrongUsername "NU"
#define MAX_USERS 10
#define MAX_ANSWER_TIME 10
#define LOGIN_WAIT 10
#define TOTAL_QUES "3"

int users[MAX_USERS][3] = {};  //index is userID, 0 is no user

void sigchld_handler(int s)
{
    while(waitpid(-1, NULL, WNOHANG) > 0);
}

//get sockaddr, IPv4 or IPv6

int timer;
void alarm_handler(int s) {
    timer = 0;
}

wrongRecv(ssize_t recvd, ssize_t expctd)
{

    if(recvd != expctd)
    {
        printf("Recvd(%zd) bytes not equal to expected(%zd) bytes\n",recvd,expctd);
        //getchar();
    }
}

//void nextQues(char* quesMsg, char* ques, char* optA, char* optB, char* optC, char* optD)
int nextQues(char* quesMsg, int QID)
{
    char ques[40], optA[10], optB[10], optC[10], optD[10], quesId[5];

    sprintf(quesId,"%d",QID);
    strncpy(ques, "This is the question?",22);
    strncpy(optA, "OptionA", 7);    strncpy(optB, "OptionB", 7);    strncpy(optC, "OptionC", 7);    strncpy(optD, "OptionD", 7);
    strncpy(quesMsg,quesId,5);
    strncpy(quesMsg + 05,ques,40);
    strncpy(quesMsg + 45,optA,10);
    strncpy(quesMsg + 55,optB,10);
    strncpy(quesMsg + 65,optC,10);
    strncpy(quesMsg + 75,optD,10);

    return 0;
}

//void answerCheck(char* ques, char* optA, char* optB, char* optC, char* optD, char* usrResponse, int rtt, int timeTaken)
void answerCheck(int fd, char usrResponse[6], int rtt, int timeTaken)
{
    int responseTime, i;
    char actualAnswer[1];
    char quesId[5];
    printf("fd(%d) quesid(%s) response(%c) rtt(%d) timeTaken(%d)\n", fd, usrResponse, usrResponse[5], rtt, timeTaken );
    strncpy(quesId, usrResponse, 5);
    actualAnswer[0] = 'B';//we have quesId we can find actual answer on basis of it

    if(actualAnswer[0] == usrResponse[5])
    {
        //printf("%s\n","+++++" );
        responseTime = timeTaken - rtt;
        //printf("Response Time(%d)\n",responseTime);

        //save it with user id

        //finding userid
        for(i = 0; i < MAX_USERS; i++) {
            if(users[i][1] == fd) {
                users[i][2] = responseTime;//saving it
                //printf("%d\n",i );
            }
        }
    }
}

int compareAnswer() {
    int i, min = 2 * MAX_ANSWER_TIME, userIndex;
    for(i = 0; i < MAX_USERS; i++) {
        if(users[i][2] < min) {
            min = users[i][2];
            userIndex = i;
        }
    }
    //Increasing Score
    users[userIndex][0]++;

    //returning fd
    return users[userIndex][1];
}

void users_deleteFd(int fd) {
    int i;
    for (i = 0; i < MAX_USERS; ++i)
    {
        if(users[i][1] == fd) {
            users[i][1] =0;
            return;
        }
    }
}

int rtt_check(int new_fd)
{
    ssize_t send_ret, recv_ret;
    char rtt_check[1];
    time_t rtt1, rtt2;

    rtt1 = time(NULL);
    send_ret = send(new_fd, "r", 1, 0);
    if(send_ret == 0)
    {
        return -2;
    }
    wrongRecv(send_ret, 1);
    //printf("%s\n","Between two phase of rttCheck" );
    recv_ret = recv(new_fd, rtt_check, 1,0);
    rtt2 = time(NULL);
    if(recv_ret == 0)
    {
        return -2;
    }
    wrongRecv(recv_ret,1);
    //printf("diff(%d)\n",(int) difftime(rtt2,rtt1));

    return  (int) difftime(rtt2,rtt1);
}

int login(char user[], char pass[])
{
    //for user
    static int Id = 0; //when have function getUserID, make it not static and also remove Id++;
    if(!strcmp(user,"abhishek") && !strcmp(pass,"abhishek")) {
        //Id = getUserID(user);
        return ++Id;
    }else if(!strcmp(user,"abhishek")){
        return 0; //wrong password
    }
    return -1; //wrong username
}

int totalQues;

int login_setup(int new_fd)
{
    //login inititalizations
    char login_det[16];
    char username[9],password[9], login_statMsg[7], totalQuesMsg[5] = TOTAL_QUES;
    totalQues = atoi(totalQuesMsg);
    //for user
    int userId;

    //for wrongRecv
    ssize_t send_ret,recv_ret;

    //getting username and password
    recv_ret = recv(new_fd,login_det,16,0);
    if(recv_ret == 0)
    {
        return -2;
    }
    wrongRecv(recv_ret,16);

    //extracting username nad password
    strncpy(username,login_det,8);  
    strncpy(password,login_det+8,8);
    username[8]='\0'; password[8]='\0';
    //printf("username(%s) and password(%s)\n",username,password);

    if( (userId = login(username,password)) > 0) {
        //printf("%d\n",userId);

        //sending status
        strncpy(login_statMsg, LOGIN_OK, 2);
        strncpy(login_statMsg + 2, totalQuesMsg , 5);
        send_ret = send(new_fd, login_statMsg,7,0);
        if(send_ret == 0)
        {
            return -2;
        }
        wrongRecv(send_ret,7);

        //TODO error checking then handling if error

        //users[userId][0] = 0; //score
        users[userId][1] = new_fd; //file descriptor associated with this user
        //users[userId][2] = 0; //answer time
        return 1;
    }
    else if(userId == -1) { //wrong username
        strncpy(login_statMsg, LOGIN_WrongUsername, 2);
        strncpy(login_statMsg + 2, totalQuesMsg , 5);
        send_ret = send(new_fd, login_statMsg,7,0);
        if(send_ret == 0)
        {
            return -2;
        }
        wrongRecv(send_ret,7);
        return 0;
    }
    else{
        strncpy(login_statMsg, LOGIN_WrongPassword, 2);
        strncpy(login_statMsg + 2, totalQuesMsg , 5);
        send_ret = send(new_fd, login_statMsg,7,0);
        if(send_ret == 0)
        {
            return -2;
        }
        wrongRecv(send_ret,7);      
        return 0;
    }
    //TODO erorr handling of above two case
    //TODO make login a loop
}


void *get_in_addr(struct sockaddr *sa)
{
    if (sa->sa_family == AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


int main(void)
{
    int listen_fd, new_fd; // listen on sock_fd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr;//connection's address info
    socklen_t sin_size;
    int yes=1;
    char s[INET6_ADDRSTRLEN];
    int rv;

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;//IPv4 or IPv6
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if((rv = getaddrinfo(NULL,PORT, &hints, &servinfo)) != 0){ //getting which IPv server supports
        fprintf(stderr, "getaddrinfo: %s\n",gai_strerror(rv));
        return 1;
    }

    //loop through all the result and bind to the first we can
    for(p = servinfo; p != NULL; p  = p->ai_next){
        if((listen_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
            perror("server : socket");
            continue;
        }

        if(setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
            perror("set sockopt");
            exit(1);
        }

        if(bind(listen_fd, p->ai_addr, p->ai_addrlen) == -1){
            close(listen_fd);
            perror("server: bind");
            continue;
        }

        break;
    }

    if(p == NULL) {
        fprintf(stderr, "server:failed to bind\n");
        return 2;
    }

    freeaddrinfo(servinfo);//all done with this structure

    if(listen(listen_fd, BACKLOG) == -1){
        perror("listen");
        exit(1);
    }
    //printf("listen_fd(%d)\n",listen_fd );

//  sa.sa_handler = sigchld_handler; // reap all dead processes
//  sigemptyset(&sa.sa_mask);
//  sa.sa_flags = SA_RESTART;
//  if(sigaction(SIGCHLD, &sa, NULL) == -1){
//      perror("sigaction");
//      exit(1);
//  }

    printf("server waiting for connections.....\n");

    fd_set master; //master file descriptor list
    fd_set read_fds; //temp file descriptor list for select()
    int fdmax;
    FD_ZERO(&master); //clear the master and temp sets
    FD_ZERO(&read_fds);

    FD_SET(listen_fd, &master);

    //keep track of the bigge file descriptor
    fdmax = listen_fd; // so far it is this one

    ssize_t recv_ret, send_ret;


    //for login
    int loginStatus;
    struct sigaction sa;
    sa.sa_handler = alarm_handler;
    sigemptyset(&sa.sa_mask);
    //sa.sa_flags = SA_RESTART;
    if(sigaction(SIGALRM, &sa, NULL) == -1){
        perror("sigaction");
        exit(1);
    }


    //login while
    alarm(LOGIN_WAIT);//accepting login only for 10 seconds
    timer = 1;
    printf("\n-----------------------------Waiting for users to login for %d seconds.-----------------------------\n",LOGIN_WAIT);
    while(timer) {
        sin_size = sizeof their_addr;
        new_fd = accept(listen_fd, (struct sockaddr *)&their_addr, &sin_size);
        if(new_fd == -1){
            //perror("accept");
            break;// this break is very important , as we are using alarm(Signals) and accept is a blocking function
                    //If accept is in blocked sate and our signal comes then accept will exit returning error. So
                    //if error then we have to break else next satements will run on falsy values.
                    //In reality we dont need this as I alredy set the SA_RESTART flag in sigaction which means
                    //after returning from the signal handler restart the activity on which you are previously
                    //instead of starting execution from next line.
        }else {

            inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
            printf("server : got connection from %s\n", s);

            //LOGIN     //need to call login function via thread because this 
                            //may stop the function if user doesnot respond
            loginStatus = login_setup(new_fd);

            //adding to select checkup
            if(loginStatus) {
                printf("User Loginned Succesfully\n");
            }
        }
    }
    printf("-----------------------------Login Closed. Now starting the QUIZ.-----------------------------\n");

    //for randome seek
    srand(time(NULL));

    //for main loop counter
    int i, win_fd;

    //for questions
    int QID = 0;
    int maxQues_Len = 40, maxOpt_len = 10, maxQuesId_len = 5;//including '\0' this time
    char quesMsg[80], answer[6];//score doesnot include \0
    //char ques[40], optA[10], optB[10], optC[10], optD[10];

    //for time calculation of each answer
    ssize_t time_ques, time_ans;

    //getting all avialable participants
    fdmax = 0;
    FD_ZERO(&master);
    for(i = 0; i < MAX_USERS; i++) {
        if( (new_fd = users[i][1]) != 0){
            FD_SET(new_fd, &master);
            if(new_fd > fdmax)
                fdmax = new_fd;
            //printf("%d\n",new_fd);
        }
    }

    int current_rtt;
    //while for main quiz
    while(totalQues--) {

        //checking who are ready for witing
        if(select(fdmax+1, NULL, &master, NULL, NULL) == -1){//here select will return withh all the descriptors which are 
                                                                //ready to write , all others have to miss this question
            perror("select");
            exit(1);
        }

        //setting which question to send
        QID++;

        //for sending questions to all
        for(i = 0; i <= fdmax; i++) {
            if(FD_ISSET(i, &master)) {
                //rtt check
                current_rtt = rtt_check(i);
                if(current_rtt == -2) {//connection closed
                    FD_CLR(i, &master);
                    users_deleteFd(i);
                    continue;
                }
                //setting question
                //nextQues(quesMsg, ques, optA, optB, optC, optD);
                nextQues(quesMsg, QID);
                printf("Sending Question QID(%s) fd(%d)\n",quesMsg,i);
                //send a question
                time_ques = time(NULL);
                send_ret = send(i, quesMsg, maxQues_Len + 4 * maxOpt_len + maxQuesId_len, 0);
                if(send_ret == 0) {//connection closed
                    FD_CLR(i, &master);
                    users_deleteFd(i);
                    continue;
                }
                wrongRecv(send_ret, maxQues_Len + 4 * maxOpt_len + maxQuesId_len);  
            }
        }

        //ASSUMING Question is send ot all the users at same time       
        //receiving and waiting for answers
        alarm(MAX_ANSWER_TIME);
        timer = 1;
        FD_ZERO(&read_fds);
        read_fds = master;
        // unsigned int qq = read_fds.fd_count;
        // for (int ii = 0; ii < qq; ++ii)
        // {
        //  printf("%d\n",read_fds.fd_array[i] );
        // }
        while(timer) {
            //printf("HURRAY\n");
            if(select(fdmax+1, &read_fds, NULL, NULL, NULL) <=0){
                perror("select");
                //exit(4);
                break;//break is important. Explained above
            }

            for(i = 0; i <= fdmax; i++) {
                //printf("Recving answer I(%d)\n",i);
                if(FD_ISSET(i, &read_fds)) {
                    //receiving answer
                    //TODO if we get answer to wrong ques
                    printf("Recving answer I(%d) fdmax (%d)\n",i,fdmax);
                    recv_ret = recv(i,answer,6,0);
                    time_ans = time(NULL);
                    wrongRecv(recv_ret,6);
                    printf("%s\n",answer );
                    if(recv_ret == 0)//connection closed
                    {
                        FD_CLR(i, &read_fds);
                        FD_CLR(i, &master);
                        users_deleteFd(i);
                        continue;
                    }else if(recv_ret > 0){
                        if(QID == atoi(answer)) { //we have received the answer to this question so remove the user from wait answer loop
                            FD_CLR(i, &read_fds);
                            //printf("%s i(%d)\n","#######",i );
                            answerCheck(i ,answer, current_rtt, (int) difftime(time_ans,time_ques));
                            //printf("Answer(%c)\n",answer[0]);
                        }
                        else{//we have recvd something unexpectable so ignore for NOW

                        }
                    }

                    //time_t cccc = time(NULL);
                    //printf("%s I(%d)\n",ctime(&cccc),i);
                }
            }
        }
        //comparing answers
        win_fd = compareAnswer();
        //sending score
    }
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define PORT "3490" //the port client will be connecting to

#define MAXDATASIZE 100 // max number of bytes we can get at once

//get sockaddr ,IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if(sa->sa_family ==AF_INET) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

wrongRecv(ssize_t recvd, ssize_t expctd)
{

    if(recvd != expctd)
    {
        printf("Recvd(%zd) bytes not equal to expected(%zd) bytes\n",recvd,expctd);
        getchar();
    }
}

void rtt_check(int sockfd)
{
    ssize_t send_ret, recv_ret;
    char rtt_check[1];
    recv_ret = recv(sockfd, rtt_check, 1,0);
    wrongRecv(recv_ret,1);
    sleep(1);//to check
    send_ret = send(sockfd, "r", 1, 0);
    wrongRecv(send_ret, 1);

    return;
}

int main(int argc, char *argv[])
{
    int sockfd, numbytes;
    char buf[MAXDATASIZE];
    struct addrinfo hints, *servinfo, *p;
    int rv;
    char s[INET6_ADDRSTRLEN];

    if(argc != 2) {
        fprintf(stderr,"usage: client hostname\n");
        exit(1);
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if((rv = getaddrinfo(argv[1], PORT, &hints, &servinfo)) != 0) {
        fprintf(stderr,"getaddrinfo: %s\n",gai_strerror(rv));
        return 1;
    }

    //lopp through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
            perror("client: socket");
            continue;
        }

        if(connect(sockfd, p->ai_addr, p->ai_addrlen) == -1){
            close(sockfd);
            perror("client: connect");
            continue;
        }

        break;
    }

    if(p ==NULL) {
        fprintf(stderr,"client: failed to connect\n");
        return 2;
    }

    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof s);
    printf("client : connecting to %s\n", s);

    freeaddrinfo(servinfo); // all done with this structure
    char login_det[17] = "abhishekabhishek";
    char login_retMsg[7], login_stat[3], totalQuesMsg[5];
    int totalQues;

    //sending login details
    ssize_t send_ret,recv_ret;
    send_ret = send(sockfd, login_det,16,0);
    wrongRecv(send_ret,16);

    //receiving login status
    recv_ret = recv(sockfd,login_retMsg,7,0);
    wrongRecv(recv_ret,7);

    strncpy(login_stat, login_retMsg, 2);
    login_stat[2] = '\0';
    printf("Login Status(%s)\n",login_stat);
    strncpy(totalQuesMsg, login_retMsg + 2, 5);
    totalQues = atoi(totalQuesMsg);
    printf("totalQues(%d)\n",totalQues);

    if(!strcmp(login_stat,"OK")) {  //login ok
        char quesId[5];
        int maxQues_Len = 40, maxOpt_len = 10, maxQuesId_len = 5;//including '\0' this time
        char quesMsg[80], scoreMsg[1];//score doesnot include \0
        char ques[40], optA[10], optB[10], optC[10], optD[10];
        char answer[6];

        while(totalQues--) {
            //checking rtt
            rtt_check(sockfd);
            //receving question
            recv_ret = recv(sockfd, quesMsg,  maxQues_Len + 4 * maxOpt_len + maxQuesId_len ,0);
            wrongRecv(recv_ret,  maxQues_Len + 4 * maxOpt_len + maxQuesId_len);
            strncpy(quesId,quesMsg,5);
            strncpy(ques, quesMsg + 05, 40);
            strncpy(optA, quesMsg + 45, 10);
            strncpy(optB, quesMsg + 55, 10);
            strncpy(optC, quesMsg + 65, 10);
            strncpy(optD, quesMsg + 75, 10);
            printf("QUESID(%s) Question(%s), A(%s) , B(%s) , C(%s) , D(%s)\n", quesId, ques, optA, optB, optC, optD);

            //choose answer
            scoreMsg[0] = 'B';

            strncpy(answer,quesId, 5);
            answer[5] = scoreMsg[0];
            sleep(5);

            //sending answer
            send_ret = send(sockfd, answer,6,0);
            wrongRecv(send_ret,6);
            printf("%s\n","Answer Message Sent" );


            // if((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
            //  perror("recv");
            //  exit(1);
            // }

            // buf[numbytes] = '\0';

            // printf("client: received '%s'\n",buf);
        }
    } 
    //TODO wrong login
    close(sockfd);
    return 0;
}