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
Unix C程序——套接字和选择函数_C_Sockets_Unix_Select - Fatal编程技术网

Unix C程序——套接字和选择函数

Unix C程序——套接字和选择函数,c,sockets,unix,select,C,Sockets,Unix,Select,我刚刚开始学习UnixC编程,有一个问题我无法解决。在这个程序中,我用socket和select函数制作了一个简单的服务器。当我使用不同的终端启动试图连接服务器的客户端程序时,服务器可以接受新的客户端并成功连接。根据我的代码,打印一个句子。然而,当我试图通过scanf和send-in-client程序将客户端程序中的消息发送到servers时,服务器只是在那里阻塞,无法接收任何消息。 你能帮我找出程序中的缺陷吗?非常感谢你的建议!! 这是我的服务器程序代码。客户端程序没有问题,我认为: 1

我刚刚开始学习UnixC编程,有一个问题我无法解决。在这个程序中,我用socket和select函数制作了一个简单的服务器。当我使用不同的终端启动试图连接服务器的客户端程序时,服务器可以接受新的客户端并成功连接。根据我的代码,打印一个句子。然而,当我试图通过scanf和send-in-client程序将客户端程序中的消息发送到servers时,服务器只是在那里阻塞,无法接收任何消息。 你能帮我找出程序中的缺陷吗?非常感谢你的建议!! 这是我的服务器程序代码。客户端程序没有问题,我认为:

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 #include <sys/types.h>
  5 #include <sys/socket.h>
  6 #include <netinet/in.h>
  7 #include <string.h>
  8 #include <fcntl.h>
  9 #include <sys/select.h>
 10 //all kinds of header 
 11 main(){
 12     int sfd;  //server's file descriptor 
 13     int fdall[100];  //array for client descriptor 
 14     int count=0;  //total number of clients
 15     int maxfd=0;   // max value of all descriptors
 16     char buf[1024]={0}; //used for receiving message from client, by recv()
 17     fd_set fds;  // readset in select()
 18     sfd=socket(AF_INET,SOCK_STREAM,0);
 19 
 20     struct sockaddr_in add;
 21     add.sin_family=AF_INET;
 22     add.sin_port=htons(9999);
 23     add.sin_addr.s_addr=inet_addr("192.168.122.1");
 24     int i,j,r;
 25 
 26     r=bind(sfd,(struct sockaddr*)&add,sizeof(add));
 27     if(r==-1) printf("bind:%m\n"),exit(-1);
 28     else puts("bind ok!");
 29     listen(sfd,10);
 30 
 31     while(1){
 32         FD_ZERO(&fds);
 33         maxfd=0;
 34         FD_SET(sfd,&fds);
 35         maxfd=maxfd>sfd?maxfd:sfd;
 36         for(i=0;i<100;i++){
 37             fdall[i]=-1;
 38         }
 39         r=select(maxfd+1,&fds,0,0,0);
 40         if(FD_ISSET(sfd,&fds)){
 41             fdall[count]=accept(sfd,0,0);
 42             puts("new client!");
 43             count++;
 44         }
 45         for(i=0;i<count;i++){
 46             if(FD_ISSET(fdall[i],&fds)!=-1&&fdall[i]!=-1){
 47                 r=recv(fdall[i],buf,1023,0);
 48                 for(j=0;j<count;j++){
 49                     if(fdall[j]!=-1){
 50                         send(fdall[j],buf,r,0);
 51                     }
 52                 }
 53             }
 54         }
 55     }
 56 }
不能使用scanf从套接字读取数据。scanf将从STDIN读取数据;这就是造成你阻塞的原因。您也不能使用fscanf,因为这需要一个文件*,尽管使用freopen可以从套接字生成一个文件,但它会假定它可以坐在那里读取其核心内容,而不是使用select


您需要做的是从套接字读入缓冲区。当您有适当数量的数据(可能由换行符分隔)时,请使用sscanf note EXTALLED s,确保正在解析的字符串以NUL结尾。

当前代码存在以下几个问题:

一,。fds集中始终只有一个套接字集。它是您正在侦听新连接的套接字。您可能也希望将所有连接到客户端的套接字放在那里

二,。测试FD_是setfdall[i],&fds=-1没有意义。FD_ISSETfdall[i],&fds类似于一个布尔值,仅测试是否等于零

三,。您的测试FD_ISSETfdall[i],&fds结果始终为零,因为您已清除fds中除sfd以外的所有值。请注意,select从不向集合中添加文件描述符。它将删除在下一次I/O操作时会阻塞的内容

四,。在每次通过大循环时,您都将fdall[i]设置为-1,尽管之前的值可能是一个打开的套接字,并且您永远不会关闭套接字

在我看来,您需要重新考虑基本功能。在大循环之前,应将fdall[i]设置为-1。在循环中,您应将所有插座从fdall[i]添加到fds。当新客户端连接时,您应在下一个循环迭代中跳过,以避免使用此新套接字测试FD_ISSET,该套接字可能超出调用select的MAXD值。希望有帮助。

检查所有库和系统调用的返回值,并打印调试消息以查找错误和意外返回值。这是解决像这样的IO代码问题的第一步。在客户端也可以这样做,而不是scanf,顺便说一句,也许你们应该在这样的应用程序中使用fgets。