Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.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
TCP多客户端服务器程序_C_Linux_Sockets_Tcp - Fatal编程技术网

TCP多客户端服务器程序

TCP多客户端服务器程序,c,linux,sockets,tcp,C,Linux,Sockets,Tcp,我正在制作一个tcp多客户端服务器聊天室。我的TCP多客户端服务器和客户端代码随附。我无法向我的程序中添加其他功能,即客户端删除。显示可以从服务器列表中删除空闲客户端。例如,如果客户机闲置30秒,则服务器应将其删除 请帮帮我。这是服务器程序 /* to compile me in Linux, type: gcc -o server t1.c -lpthread */ /* t1.c - code for server program that uses TCP/IP */ /*

我正在制作一个tcp多客户端服务器聊天室。我的TCP多客户端服务器和客户端代码随附。我无法向我的程序中添加其他功能,即客户端删除。显示可以从服务器列表中删除空闲客户端。例如,如果客户机闲置30秒,则服务器应将其删除

请帮帮我。这是服务器程序

 /* to compile me in Linux, type:  gcc -o server t1.c -lpthread */  
 /* t1.c - code for server program that uses TCP/IP */  
 /****SERVER CODE****/  
 #include <stdio.h>            
 #include <stdlib.h>            
 #include <sys/socket.h>          //for sockets  
 #include <sys/types.h>            
 #include <string.h>          //for string operations  
 #include <netinet/in.h>          //Internet Protocol family sockaddr_in defined here   
 #include <pthread.h>          // for the cosy POSIX threads  
 #include <arpa/inet.h>          // for inet_ntoa() function  
 #include <unistd.h>          //NULL constant defined here  
 #include <signal.h>          //for ctrl+c signal  
 #define BACKLOG 100          // connections in the queue  
 #define MAXDATALEN 256           //max size of messages to be sent  
 #define PORT 2012          //default port number  
 /*Note:  The port argument is optional. If no port is specified,  
  *     the server uses the default given by PORT.*/  
   struct Node                         /*structure to handle all clients*/  
     {  
       int port;  
        char username[10];  
       struct Node *next;  
     };  
   typedef struct Node *ptrtonode;  
   typedef ptrtonode head;  
   typedef ptrtonode addr;  
      void sendtoall(char *,int new_fd);     /*send chat msgs to all connected clients*/  
      void Quitall( );               /*send msg to all if server shuts down*/  
      head MakeEmpty( head h );          /*clearing list*/  
      void Delete( int port, head h );     /*delete client values on client exit*/  
      void Insert(int port,char*,head h,addr a);/*inserting new client */  
      void DeleteList( head h );          /*clearing list*/  
      void Display( const head h );          /*list all clients connected*/  
      void *Quitproc( );                /*signal handler*/  
      void *server(void * arg);          /*server instance for every connected client*/  
      void zzz();  
      char      username[10];          /*size of username*/  
      int sf2;  
      head h;                    /*variable of type struct head*/  
      char     buffer[MAXDATALEN];  
      /******main starts ***********/  
 int main(int argc, char *argv[]) {  
      int       sockfd,new_fd;                /*variables for socket*/  
      int      portnum;               /*variable for port numb if provided*/  
      struct sockaddr_in      server_addr;     /*structure to hold server's address */  
      struct sockaddr_in      client_addr;     /*structure to hold client's address */  
      int      cli_size,z;               /*length of address */  
      pthread_t      thr;               /*variable to hold thread ID */  
      int      yes=1;  
       addr a;                         /*variable of type struct addr*/  
      printf("\n\t*-*-*-*SERVER STARTED*-*-*-*\n");  
      /*=optional or default port argument=*/  
  if( argc == 2 )       
       portnum = atoi(argv[1]);  
  else   
      portnum = PORT; //if port number not given as argument then using default port  
      printf("PORT NO.:\t%d\n",portnum);  
      h = MakeEmpty( NULL );          //frees the list  
      /*=set info of server =*/  
      server_addr.sin_family=AF_INET;          /* set family to Internet   */  
      server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* set IP address */  
      server_addr.sin_port=htons(portnum);  
       printf("IP ADDRESS:\t%s\n",inet_ntoa(server_addr.sin_addr));  
      /*=creating socket=*/  
      sockfd = socket(AF_INET, SOCK_STREAM, 0);  
   if(sockfd == -1){  
      printf("server- socket() error");     // debugging  
      exit(1);  
   }else  
      printf("socket\t\tcreated.\n");  
   if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,sizeof(int)) == -1) {  
      printf("setsockopt error");     // debugging  
      exit(1);  
   }else printf("reusing\t\tport\n");  
      /*=binding socket=*/  
   if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr))==-1){  
           printf("binding failed\n");     // debugging  
      exit(1);}  
   else   
      printf("binding\t\tsuccess.\n\n");  
 printf("\t\tPRESS CTRL+z TO VIEW ONLINE CLIENTS\n\n");  
      /*=socket on listening mode=*/  
      listen(sockfd, BACKLOG);  
      printf("waiting for clients......\n");  
   if (signal(SIGINT,(void *)Quitproc)==0)     //signal handler  
   if(signal(SIGTSTP, zzz)==0)               //signal handler  
   while(1){  
             cli_size=sizeof(struct sockaddr_in); //cli_size necessary as an argument for pthread_create  
             new_fd = accept(sockfd, (struct sockaddr *)&client_addr,&cli_size); //accepting connection from client   
             a =h ;  
           /*=sign in with name=*/  
           bzero(username,10);            
           if(recv(new_fd,username,sizeof(username),0)>0);  
             username[strlen(username)-1]=':';  
             printf("\t%d->%s JOINED chatroom\n",new_fd,username);  
             sprintf(buffer,"%s IS ONLINE\n",username);  
             Insert( new_fd,username, h, a );               //inserting newly accepted client socked fd in list  
             a = a->next;  
           /*=notify all clients about newly joining clients=*/   
             a = h ;  
           do{  
             a = a->next;  
             sf2 = a->port;  
           if(sf2!=new_fd)  
           send(sf2,buffer ,sizeof(buffer),0);  
           } while( a->next != NULL );  
              printf("server got connection from %s & %d\n\n",inet_ntoa(client_addr.sin_addr),new_fd); // debugging  
            struct Node args;                          //struct to pass multiple arguments to server function  
             args.port=new_fd;  
             strcpy(args.username,username);  
            pthread_create(&thr,NULL,server,(void*)&args);      //creating thread for every client connected   
            pthread_detach(thr);  
       } /*while end*/  
  DeleteList(h);                          //deleting all clients when server closes  
  close(sockfd);  
 }/********main ends***********/  
      /*******ALL FUNCTIONS DEFINED BELOW*********/  
 /* ==========Server function for every connected Client =========*/  
 void *server(void * arguments){  
  struct Node *args=arguments;  
  char     buffer[MAXDATALEN],ubuf[50],uname[10];     /* buffer for string the server sends */   
  char *strp;            
  char      *msg = (char *) malloc(MAXDATALEN);  
  int      ts_fd,x,y;  
  int      sfd,msglen;  
  ts_fd = args->port;      /*socket variable passed as arg*/  
  strcpy(uname,args->username);   
  addr      a;  
       /*=sending list of clients online=*/  
       a =h ;  
           do{  
           a = a->next;  
           sprintf( ubuf," %s is online\n",a->username );  
           send(ts_fd,ubuf,strlen(ubuf),0);  
           } while( a->next != NULL );  
       /*=start chatting=*/  
   while(1){  
        bzero(buffer,256);  
        y=recv(ts_fd,buffer,MAXDATALEN,0);  
       if (y==0)   
       goto jmp;  
        /*=if a client quits=*/  
       if ( strncmp( buffer, "quit", 4) == 0 ){  
      jmp:     printf("%d ->%s left chat deleting from list\n",ts_fd,uname);  
           sprintf(buffer,"%s has left the chat\n",uname);  
           addr a = h ;  
           do{  
                a = a->next;  
                sfd = a->port;  
                if(sfd == ts_fd)   
                 Delete( sfd, h );  
                if(sfd != ts_fd)   
                 send(sfd,buffer,MAXDATALEN,0);  
            }while ( a->next != NULL );  
                Display( h );  
                close(ts_fd);  
                free(msg);  
             break;  
            }  
      /*=sending message to all clients =*/  
      printf("%s %s\n",uname,buffer);  
      strcpy(msg,uname);  
      x=strlen(msg);  
      strp = msg;  
      strp+= x;  
      strcat(strp,buffer);  
      msglen=strlen(msg);  
        addr a = h ;  
      do{  
       a = a->next;  
       sfd = a->port;  
      if(sfd != ts_fd)   
        send(sfd,msg,msglen,0);  
      } while( a->next != NULL );  
       Display( h );  
       bzero(msg,MAXDATALEN);  
   }//end while  
    return 0;  
 }// end server  
 /*=====empties and deletes the list======*/  
 head MakeEmpty( head h )  
      {  
      if( h != NULL )  
           DeleteList( h );  
           h = malloc( sizeof( struct Node ) );  
      if( h == NULL )  
           printf( "Out of memory!" );  
           h->next = NULL;  
      return h;  
      }  
 /*======delete list=======*/  
 void DeleteList( head h )  
      {  
      addr a, Tmp;  
      a = h->next;   
      h->next = NULL;  
           while( a != NULL )  
           {  
           Tmp = a->next;  
           free( a );  
           a = Tmp;  
           }  
      }  
 /*===============inserting new clients to list==========*/  
 void Insert( int port,char *username, head h, addr a )  
      {  
      addr TmpCell;  
      TmpCell = malloc( sizeof( struct Node ) );  
           if( TmpCell == NULL )  
           printf( "Out of space!!!" );  
      TmpCell->port = port;  
      strcpy(TmpCell->username,username);  
      TmpCell->next = a->next;  
      a->next = TmpCell;  
      }  
 /*========displaying all clients in list==================*/  
 void Display( const head h )  
      {  
        addr a =h ;  
        if( h->next == NULL )  
      printf( "NO ONLINE CLIENTS\n" );  
        else  
        {  
           do  
           {  
             a = a->next;  
             printf( "%d->%s \t", a->port,a->username );  
           } while( a->next != NULL );  
           printf( "\n" );  
        }  
      }  
 /*===========client deleted from list if client quits================*/  
 void Delete( int port, head h ){  
        addr a, TmpCell;  
        a = h;  
    while( a->next != NULL && a->next->port != port )  
       a = a->next;  
   if( a->next != NULL ){             
      TmpCell = a->next;  
      a->next = TmpCell->next;   
      free( TmpCell );  
   }  
  }  
 /*======handling signals==========*/  
 void *Quitproc(){        
      printf("\n\nSERVER SHUTDOWN\n");  
      Quitall( );  
     exit(0);  
  }  
 /*===============notifying server shutdown===========*/  
 void Quitall(){  
   int sfd;  
   addr a = h ;  
   int i=0;  
    if( h->next == NULL ) {  
     printf( "......BYE.....\nno clients \n\n" );  
      exit(0);  
     } else {  
        do{  
          i++;  
         a = a->next;  
         sfd = a->port;  
         send(sfd,"server down",13,0);  
         } while( a->next != NULL );  
       printf("%d clients closed\n\n",i);         
       }  
  }  
 void zzz(){  
   printf("\rDISPLAYING ONLINE CLIENTS\n\n");  
   Display(h);  
  }  
 /*=====================================================================================================*/  

Here is the client program

 /* To compile me in Linux type: gcc -o client t2.c -lpthread*/  
 /* t2.c - code for client that uses TCP     */  
 /***CLIENT CODE*/  
 #include <stdio.h>  
 #include <stdlib.h>        
 #include <string.h>          //for string operations  
 #include <unistd.h>          //NULL constant defined here  
 #include <sys/types.h>            
 #include <sys/socket.h>          //for sockets  
 #include <netinet/in.h>          //Internet Protocol family sockaddr_in defined here   
 #include <pthread.h>          // for the cosy POSIX threads  
 #include <signal.h>          //for ctrl+c signal  
 #define MYPORT 2012     /* default port number */  
 #define MAXDATALEN 256  
 int      sockfd;  
 int      n,x;                         /*variables for socket*/  
 struct sockaddr_in serv_addr;          /* structure to hold server's address */  
 char      buffer[MAXDATALEN];  
 char      buf[10];            
 void *quitproc();  
 void* chat_write(int);  
 void* chat_read(int);  
 void *zzz();  
 /***************main starts************/  
 int main(int argc, char *argv[]){  
  pthread_t thr1,thr2;          /* variable to hold thread ID */  
     if( argc != 2 ){       
       printf("help:u need to put server ip\n");  
       exit(0);  
       }  
      /*=============socket creating==============*/  
      sockfd = socket(AF_INET, SOCK_STREAM, 0);  
      if (sockfd == -1)  
        printf ("client socket error\n");  
      else       
        printf("socket\t\tcreated\n");  
      /*===============set info===================*/  
      bzero((char *) &serv_addr, sizeof(serv_addr));  
      serv_addr.sin_family = AF_INET;  
      serv_addr.sin_port = htons(MYPORT);  
      serv_addr.sin_addr.s_addr = inet_addr(argv[1]);  
      /*=========for username=====================*/  
      bzero(buf,10);  
      printf("\nENTER YOUR NAME::");  
      fgets(buf,10,stdin);  
      __fpurge(stdin);       
      buf[strlen(buf)-1]=':';  
      /*=============client connect to server============*/  
      if(connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))==-1)  
      {  
        printf("client connect error\n");  
        exit(0);  
      }  
      else  
        printf("%s connected to server\n",buf);  
      printf("\rYOU JOINED AS- %s",buffer-1);  
      send(sockfd,buf,strlen(buf),0);  
      pthread_create(&thr2,NULL,(void *)chat_write,(void *)sockfd);     //thread creation for writing  
      pthread_create(&thr1,NULL,(void *)chat_read,(void *)sockfd);     //thread creation for reading  
      pthread_join(thr2,NULL);  
      pthread_join(thr1,NULL);  
      return 0;  
 } /*main ends*/  
 /*======================================================================*/  
 /*======reading continously from socket=============*/  
 void* chat_read(int sockfd)  
 {  
      if (signal(SIGINT,(void *)quitproc)==0)  
      if(signal(SIGTSTP, (void *)zzz)==0)  
      while(1)  
      {  
        n=recv(sockfd,buffer,MAXDATALEN-1,0);  
         if(n==0){   
            printf("\nDUE TO SOME UNEXPECTED REASONS SERVER HAS BEEN SHUTDOWN\n\n");  
             exit(0);  
             }  
         if(n>0){  
              printf("\n%s ",buffer);  
            bzero(buffer,MAXDATALEN);  
             }  
      }//while ends  
 }  
 /*======writing continously to socket=============*/  
 void* chat_write(int sockfd)  
 {  
      while(1)  
      {  
        printf("%s",buf);  
          fgets(buffer,MAXDATALEN-1,stdin);  
         if(strlen(buffer)-1>sizeof(buffer)){  
             printf("buffer size full\t enter within %d characters\n",sizeof(buffer));  
             bzero(buffer,MAXDATALEN);  
             __fpurge(stdin);  
             }  
        n=send(sockfd,buffer,strlen(buffer),0);  
         if(strncmp(buffer,"quit",4)==0)  
             exit(0);  
         bzero(buffer,MAXDATALEN);  
      }//while ends  
 }  
 /*======handling signals==========*/  
 void *quitproc(){            //handling ctrl+d  
    printf("\rPLEASE TYPE 'quit' TO EXIT\n");  
 }  
 void *zzz(){               //handling ctrl+z  
    printf("\rPLEASE TYPE 'quit' TO EXIT\n");  
 }  
 /*=================================================================*/  
/*要在Linux中编译我,请键入:gcc-oservert1.c-lpthread*/
/*t1.c—使用TCP/IP*的服务器程序的代码
/****服务器代码****/
#包括
#包括
#包括//用于套接字
#包括
#包含//用于字符串操作
#包括//此处定义的Internet协议系列sockaddr\u
#包括//用于cosy POSIX线程
#include//for inet\u ntoa()函数
#包含//此处定义的空常量
#包含//用于ctrl+c信号
#定义队列中的积压100//连接
#定义MAXDATALEN 256//要发送的消息的最大大小
#定义端口2012//默认端口号
/*注意:端口参数是可选的。如果未指定端口,
*服务器使用端口提供的默认值。*/
结构节点/*用于处理所有客户端的结构*/
{  
国际港口;
字符用户名[10];
结构节点*下一步;
};  
typedef结构节点*ptrtonode;
typedef PTRTO节点头;
typedef ptrtonode addr;
void sendtoall(char*,int new_fd)/*向所有连接的客户端发送聊天MSG*/
void-Quitall()/*如果服务器关闭,向所有人发送消息*/
水头变空(水头h)/*结算清单*/
无效删除(内部端口,头部h)/*在客户端退出时删除客户端值*/
无效插入(内部端口,字符*,标题h,地址a)/*插入新客户端*/
无效删除列表(标题h)/*结算清单*/
无效显示(const head h)/*列出所有已连接的客户端*/
void*Quitproc()/*信号处理器*/
void*服务器(void*arg)/*每个连接的客户端的服务器实例*/
void zzz();
字符用户名[10]/*用户名大小*/
int sf2;
头部h/*结构头类型的变量*/
字符缓冲区[MAXDATALEN];
/******主启动装置*********/
intmain(intargc,char*argv[]){
int sockfd,套接字的新_fd;/*变量*/
int portnum;/*端口号变量(如果提供)*/
server_addr;/*结构中的struct sockaddr_保存服务器地址*/
客户端中的struct sockaddr\u\u addr;/*用于保存客户端地址的结构*/
int cli_size,z;/*地址长度*/
pthread_t thr;/*用于保存线程ID的变量*/
int yes=1;
addr a;/*类型为struct addr*/
printf(“\n\t*-*-*-*服务器已启动*-*-*-*\n”);
/*=可选或默认端口参数=*/
如果(argc==2)
portnum=atoi(argv[1]);
其他的
portnum=PORT;//如果端口号未作为参数提供,则使用默认端口
printf(“端口号:\t%d\n”,portnum);
h=MakeEmpty(NULL);//释放列表
/*=服务器的设置信息=*/
服务器地址sin\u family=AF\u INET;/*将family设置为Internet*/
服务器\u addr.sin\u addr.s\u addr=htonl(INADDR\u ANY);/*设置IP地址*/
服务器地址sin\u port=htons(portnum);
printf(“IP地址:\t%s\n”,inet\u ntoa(服务器地址sin\u地址));
/*=正在创建套接字=*/
sockfd=套接字(AF_INET,SOCK_STREAM,0);
如果(sockfd==-1){
printf(“server-socket()错误”);//调试
出口(1);
}否则
printf(“套接字\t\t已创建。\n”);
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int))=-1{
printf(“setsockopt错误”);//调试
出口(1);
}else printf(“重用\t\tport\n”);
/*=绑定套接字=*/
if(bind(sockfd,(struct sockaddr*)和server_addr,sizeof(struct sockaddr))=-1{
printf(“绑定失败\n”);//调试
退出(1);}
其他的
printf(“绑定\t\t成功。\n\n”);
printf(“\t\t按CTRL+z以查看联机客户端\n\n”);
/*=侦听模式上的套接字=*/
倾听(sockfd,BACKLOG);
printf(“等待客户……”\n);
if(signal(SIGINT,(void*)Quitproc)=0)//信号处理程序
if(信号(SIGTSTP,zzz)==0)//信号处理程序
而第(1)款{
cli_size=sizeof(struct sockaddr_in);//cli_size必须作为pthread_create的参数
new_fd=accept(sockfd,(struct sockaddr*)&client_addr,&cli_size);//接受来自客户端的连接
a=h;
/*=使用name=*/登录
bzero(用户名,10);
如果(recv(new_fd,username,sizeof(username),0)>0);
用户名[strlen(username)-1]=':';
printf(“\t%d->%s加入聊天室\n”,新的\u fd,用户名);
sprintf(缓冲区,“%s处于联机状态\n”,用户名);
Insert(new_fd,username,h,a);//在列表中插入新接受的客户机套接字fd
a=a->next;
/*=通知所有客户有关新加入的客户=*/
a=h;
做{
a=a->next;
sf2=a->端口;
如果(sf2!=新的\u fd)
发送(sf2,缓冲区,sizeof(缓冲区),0);
}while(a->next!=NULL);
printf(“服务器从%s&%d获得连接\n\n”,inet\u ntoa(client\u addr.sin\u addr),new\u fd);//调试
struct Node args;//将多个参数传递给服务器函数的struct
struct timeval tv;

tv.tv_sec = 30;  /* 30 Secs Timeout */
tv.tv_usec = 0;  

setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));