我有一个通过套接字连接的客户端.NET应用程序和服务器.NET应用程序。
客户端每500毫秒发送20个左右的字符的字符串。
在我的本地开发计算机上,这可以正常工作,但是一旦客户端和服务器位于两台不同的服务器上,则服务器在发送字符串时不会立即接收到该字符串。客户端仍然发送完美,我已经与Wireshark确认了这一点。我还确认服务器是否每500毫秒接收一次字符串。
问题是我等待消息的服务器应用程序实际上仅每20秒左右接收一次消息,然后从这20秒接收所有内容。
我使用异步套接字,由于某种原因,回调仅每20秒被调用一次。
在AcceptCallback
中,它建立连接并调用BeginReceive
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
这在我的本地计算机上有效,但是在我的生产服务器上,ReadCallback不会立即发生。
BufferSize设置为1024。我还尝试将其设置为10。一旦调用ReadCallback,它一次就会从套接字读取多少数据,所以这有所不同,但这并不是真正的问题。一旦调用ReadCallback,其余的就可以正常工作。
我正在使用Microsoft的Asynchronous Server Socket Example,因此您可以在其中看到我的ReadCallback方法的外观。
当数据到达服务器时,如何立即获取BeginReceive回调?
--
更新
这已经解决了。这是因为服务器具有单个处理器和单个内核。添加另一个内核后,该问题立即得到解决。现在,当调用进入服务器时,将立即调用ReadCallback。
谢谢大家的建议!!
最佳答案
应OP的要求,在此处复制我的“评论/答案”。
我的猜测是,问题出现是由于单核计算机上的线程调度。这是一个老问题,在超线程/多核处理器的现代时代几乎已不复存在。在程序执行过程中生成线程时,需要计划的时间才能运行。
在单核计算机上,如果一个线程继续执行而没有显式地将控制权传递给OS调度程序(通过等待互斥锁/信号或通过调用Sleep),则任何其他线程的执行(在同一进程中并具有较低的优先级)可能被调度程序无限期地推迟。因此,在所描述的情况下,异步网络线程(最有可能)只是饿死了执行时间-有时仅获得碎片。
很明显,添加第二个CPU/内核可以通过提供并行调度环境来解决该问题。