2012-10-17 182 views
2

我读过Winsock上的send()函数,直到收到最后一个数据包的ACK。现在我正在玩一款基于回合制角色扮演游戏的服务器。一切都由一个线程处理(对于64个套接字)。接收到请求后,处理并写入套接字的响应。这个过程不能被打断。Winsock send()阻止服务器?

是否可以使用此方法处理1000个客户端(每个64个套接字一个线程)?

如果send()花费很长时间才能完成,或者客户端恶意不发送ACK或连接中断,是不是会阻塞整个服务器?

我应该把网络和请求处理的逻辑分成2个线程吗?如果是这样,处理网络传输的线程仍可能被send()或recv()阻塞。

或者最好是使用重叠I/O?

回答

3

send()只有当套接字在阻塞模式下运行并且套接字的出站缓冲区填满了排队数据时才会阻塞。如果您在同一个线程中管理多个套接字,请不要使用阻塞模式。如果一个接收者没有及时读取数据,它可能会导致该线程上的所有连接都受到影响。如果使用非阻塞模式,则send()将在套接字进入发生阻塞的状态时报告,然后您可以使用select()来检测套接字何时可以再次接受新数据。更好的选择是使用重叠的I/O或I/O完成端口。将出站数据提交给操作系统,让操作系统处理所有等待您的数据,并在数据最终被接受/发送时通知您。在收到该通知之前,不要为给定套接字提交新数据。对于大量连接的可扩展性,I/O完成端口通常是更好的选择。

+0

你能解释为什么如果使用多个线程会有所不同?套接字是通过线程共享的吗? – Jori

0

不,它不能这样工作。从MSDN文档上send

一个成功完成发送功能并不表明数据已成功交付和接收到收件人。此功能仅表示数据已成功发送。

+0

除此之外,它实际上并不表示数据已成功发送**到接收方,而是已成功**排队在接收方的出站缓冲区中以便稍后传输到接收方。如果'send()'阻塞,则意味着套接字正在阻塞模式下运行,并且队列已满,等待接收器读取并确认一些数据,以便在队列中打开空闲空间。 –