大容量TCP客户端设计
我有一个.NET TCP客户端,可以将大量消息发送到(.NET异步)TCP服务器。
我需要继续向服务器发送消息,但是由于TIME_WAIT,我的客户端端口用完了。
程序如何在不使用所有可用端口的情况下连续可靠地发送消息?
有没有一种方法可以保持重复使用相同的套接字。我已经看过Disconnect()和REUSEADDRESS套接字标志,但是找不到它们使用的任何好例子。实际上,大多数消息来源说不要使用Disconnect,因为它是用于较低级别的用途(即,它仅回收套接字句柄)。
我在想我需要切换到UDP,或者也许有一种使用C ++和IOCP的方法?
解决方案
客户端可以保持同一个套接字打开并循环发送消息吗?
open socket connection while(running) send messages over socket close socket connection
当这样编码时,它不起作用。
服务器仅收到第一条消息。
当我打开和关闭套接字时,服务器可以工作,但客户端端口用完了。
我猜这是服务器的设计导致我不得不像这样对客户端进行编码。
因此,如何使用.NET编写一个异步服务器代码。我在网上跟随了MSDN示例和大量示例。
消息队列服务中的某些内容对项目有好处吗?这样,客户端可以将尽可能多的消息传递到服务器,并且服务器可以在可能的情况下尽可能快地从队列中提取这些消息,并且如果客户端发送的消息超出了它的处理能力,它们将变得很简单输入队列并等待处理。
一些快速Googling提出了有关使用C#构建消息队列服务的MSDN文档。
编写TCP服务器(使用任何语言)的基本思想是打开一个端口以侦听连接,然后创建新的线程或者进程来处理新的连接请求。
open a server socket // this uses the port the clients know about while(running) client_socket = server_socket.listen fork(new handler_object(client_socket))
这是C#中的一个很好的例子。
如果服务器和客户端知道数据格式,则可以保持套接字打开。我们正在关闭套接字,以便服务器可以"看到"客户端"完成"。
如果我们有某种协议,则服务器可以在完成接收数据块后"知道"。
我们可以查找某种类型的消息结束令牌,可以传入消息的长度,然后根据大小读取其余消息,等等。不同的处理方式。
但是没有理由不断打开和关闭与服务器的连接-这就是在这里杀死原因。
TCP非常努力地防止网络拥塞。所有新的TCP连接均以"慢启动"状态开始,在该状态下,它们仅发送一个数据包,并等待另一端的确认。如果收到ACK,则TCP将发送两个数据包,然后发送四个数据包,依此类推,直到达到其最大窗口大小。
如果要以高数据速率生成消息,则确实要避免打开和关闭TCP连接。每次打开新连接时,启动速度都会很慢。如果我们可以保持套接字打开状态,则TCP连接将超过缓慢的启动状态,并能够以更高的速率发送数据。
为此,我们需要使服务器处理一个连接上的多个消息(这意味着找到一种描述每个消息的方法)。如果服务器支持任何类型的HTTP编码,则可以使用;确保检查与"持久"连接或者HTTP 1.1相关的任何参数或者配置,因为这是HTTP通过单个TCP连接发送多个请求的方式。
我们提到的一种选择是UDP。如果我们以相当高的速率生成消息,则由于队列中某个地方的队列满了,我们很可能会丢失其中的一些消息。如果我们发送的消息需要可靠,则UDP可能不是一个很好的基础。