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函数的使用(附源码)