ioctlsocket 或 recv 在 Windows 套接字编程中需要更多时间来执行?

Posted

技术标签:

【中文标题】ioctlsocket 或 recv 在 Windows 套接字编程中需要更多时间来执行?【英文标题】:ioctlsocket or recv takes more time to execute in windows socket programming? 【发布时间】:2011-11-29 14:02:18 【问题描述】:

在套接字编程中,一些数据被发送到服务器,服务器一收到就发送确认响应消息。它超过 1 个字节,所以我在接收时检查多个字节,这里我丢失了大约 120-200 毫秒。这是一个非常大的问题。由于客户端需要为此确认发送回 ack。我已经嗅到了数据在服务器发送的同时到达了我的 IP。但是 recv 或 ioctlsocket(检查超过 1 个字节是否可以读取)需要时间来读取超过一个字节。我该如何解决这个问题。代码如下。

        DWORD RecvCount = 0;    
        char szBuff1[2048];         
        bool stop = false;          
        while(!stop)
                       
            ioctlsocket(*socket, FIONREAD, &RecvCount);
            if(RecvCount > 1)
                stop = true;
        
        int Res = recv(*socket, szBuff1, RecvCount,0);

【问题讨论】:

你真的应该使用select,而不是忙着循环ioctl。我怀疑这样做会大大降低您的延迟。 select 正在工作,但服务器会先给出 Ack 然后响应,一切都在同一毫秒内,但只有 ack 到来后,socket 已从 select 中准备好,我还需要等待另一个响应。如何我去解决这个问题。 您可以轻松地循环阅读。重复,直到您收到完整的消息(或超时)。 循环遍历需要时间。(100-200 毫秒)。我不想失去。我从服务器获得响应但在套接字中不可用的同一毫秒。我已经嗅探到数据已到达我的 IP。 它真的不应该花费〜200ms,如果您使用阻塞套接字,您可以再次调用recv,当数据再次可用时它将唤醒。 select 单个套接字也不应该花那么长时间(请注意,循环时不需要再次将套接字集归零,只需确保你的套接字在集合中。如果你是只检查一个套接字的可读性) 【参考方案1】:

您应该在 Windows 上禁用 Nagle 算法,否则套接字将停留在您的数据上,直到缓冲区已满(或者至少在发送之前等待几百毫秒)。

您可以通过设置 TCP_NODELAY 套接字选项来做到这一点:

int flag = 1;
int result = setsockopt(m_Socket,IPPROTO_TCP,TCP_NODELAY,(char *) &flag,sizeof(int));

【讨论】:

只在发送时相关,与接收无关。

以上是关于ioctlsocket 或 recv 在 Windows 套接字编程中需要更多时间来执行?的主要内容,如果未能解决你的问题,请参考以下文章

mingw 中 ioctlsocket 的 SIOCGIFHWADDR

如何在 linux C 中解除对 recv() 或 recvfrm() 函数的阻塞

VC++ socket编程中设置socket选项的ioctlsocketsetsockopt和WSAIoctl函数的使用(附源码)

recv 问题时套接字关闭

设置非阻塞的套接字Socket

recv函数返回啥值?