c中的非阻塞套接字 [英] Non blocking socket in c

查看:139
本文介绍了c中的非阻塞套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在开发单个服务器,单客户端udp聊天应用程序。最初我使用阻塞套接字,这是默认条件。现在我想将套接字转换为非阻塞,以便客户端和服务器之间的通信可以在没有转弯障碍的情况下完成...我现在已经在服务器端实现了select功能,但是它何时启动客户端获取一次在服务器端显示的消息,之后客户端和服务器都没有响应,所以现在我展示了如何在服务器端实现select()函数:

Currently I am working on a single server,single client udp chat application. Initially I used blocking sockets which is the default condition. Now I want to convert the socket into non-blocking so that communication between client and server could be done without the obstacle of turns... I''ve implemented the select function on the server side for now,but the when it starts the client gets to send a message once which is displayed on the server side,afterwards both client and server get irresponsive, so now I am showing how have I implemented the select() function on the server side:

//Declaring a non-blocking structure
              fd_set readfds,writefds;
           // clear the set ahead of time
              FD_ZERO(&readfds);
              FD_ZERO(&writefds);
           // add our descriptor to the set
              FD_SET(sd, &readfds);
              FD_SET(sd, &writefds);
              /value of sd+1
              int n=sd+1;





因为我想同时收到并发送数据,我已经在循环中实现了选择功能:





Since I want to both receive and send data,I''ve implemented the select funtion in the loop:

int client_length = (int)sizeof(struct sockaddr_in);
                int rv = select(n, &readfds, NULL, NULL, NULL);
                if(rv==-1)
                {
                 printf("Error in Select!!!\n");
                 exit(0);
                }
               else if(rv==0)
                { 
                 printf("Timeout occurred\n");
                }
               else 
                if (FD_ISSET(sd, &readfds))
                {
                int bytes_received = recvfrom(sd, buffer,SIZE, 0, (struct sockaddr *)&client, &client_length);
                if (bytes_received < 0)
               {
               fprintf(stderr, "Could not receive datagram.\n");
               closesocket(sd);
               WSACleanup();
               exit(0);
              }
                }





进一步发送数据:





further for sending data:

fgets(buffer,SIZE,stdin);
              int rv1 = select(n, &writefds, NULL, NULL, NULL);
              if(rv1==-1)
              {
           printf("Error in Select!!!\n");
           exit(0);
              }
             else if(rv1==0)
             {
            printf("Timeout occurred\n");
             }
            else 
             if(FD_ISSET(sd,&writefds))
                  {
                     if(sendto(sd, buffer,strlen(buffer), 0, (struct sockaddr *) &client,client_length)<0)
                         {
                            printf("Error sending the file! \n");
                            exit(1);
                         }
                  }

                }

推荐答案

我看不到任何调用设置套接字以非阻塞模式工作。您是否看过 ioctl [ ^ ](可选 ioctlsocket [ ^ ] for win32)与FIOASYNC和/或FIOBNIO [ ^ ]选项?



这是'第一个 tut link [ ^ ]我来自谷歌。你可能会找到更好的。



我希望这有帮助



[修改]另外,取决于你需要和其他负载期望,正如谢尔盖上面指出的那样,应该考虑使用带阻塞调用的线程[/ Modification]
I couldn''t see any calls setting the socket to work in non-blocking mode. Did you take a look at ioctl[^] (optionally ioctlsocket[^] for win32) with the FIOASYNC and/or FIOBNIO[^] options?

Here''s the first tut link[^] I got from google. You might find better ones.

I hope this helps

[Modification] Also, depending on you requirement and other load expectations, as Sergey pointed out above, using threads with blocking calls should be considered [/Modification]


即使你使用select,你也必须将套接字转换为非阻塞模式()和它的朋友。在某些版本的Windows上,select()能够虚假地唤醒,因为网络堆栈接收到一些数据,但是当你真正开始读取套接字时,它会发现接收到的数据的crc不能让你的读数保持不变如果套接字没有变为非阻塞状态,则阻塞状态。这可能也发生在非Windows操作系统上。您的代码的另一个问题是您应该使用单个select调用来处理等待读/写操作。

You have to turn the socket into nonblocking mode even if you are using select() and its friends. On some versions of windows select() is able to wake up spuriously because the network stack receives some data but when you actually start reading the socket it can find out that the crc of the received data isn''t OK leaving your reading in a blocking state if the socket isn''t turned into non-blocking. This may happen also on non-windows OS-es. Another problem with your code is that you should handle the wait for read/write operations with a single select call.
int rv = select(n, &readfds, &writefds, NULL, NULL);


这篇关于c中的非阻塞套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆