关于MSDN杂志的TCP异步服务器的问题

问题描述 投票:0回答:2

this MSDN Magazine August 2005 article中,Daryn Kiely解释了构建TCP服务器的三种方法。

第三个模型,即异步模型,是最适合我的需求的模型,但是我在理解其内部工作的某些细节方面有些麻烦。

问题1-关于接受连接的线程数

在此示例中,通过调用Start()启动服务器时,代码创建了十个接受连接的ThreadPool:

public void Start()
{
    SetupServerSocket();
    for (int i = 0; i < 10; i++)
        _serverSocket.BeginAccept(AsyncCallback(AcceptCallback), _serverSocket);
}

我不明白为什么您不能只使用一个_serverSocket.BeginAccept,为什么不能使用十。

问题2 –大约收到零字节

ReceiveCallback()中,如果我们收到零字节,则会关闭连接。为什么?当总是收到零字节时,是否认为客户端已关闭连接?在我这里所做的测试中,当客户端关闭连接时,我收到一个在SocketException中捕获的异常。我在这里想念什么吗?

问题3 –关于是否需要再次开始接收

在套接字中接收到某些内容后,将其放回BeginReceive。为什么我们需要再次开始接收?这不应该自动吗?

问题4 –关于缓冲区大小

使用255个字节的缓冲区。我知道,如果一条消息的长度大于缓冲区的大小,则它将在多个接收中碎片化。我应该设置一个足够大的缓冲区大小以保证没有消息会被碎片化,还是我必须提供代码来处理消息碎片(将多个接收合并到一个缓冲区中)?

c# networking tcp tcpserver
2个回答
3
投票

问题1-关于接受连接的线程数

在此示例中,通过调用Start()启动服务器时,代码创建了十个接受连接的ThreadPool:

public void Start()
{
    SetupServerSocket();
    for (int i = 0; i < 10; i++)
        _serverSocket.BeginAccept(AsyncCallback(AcceptCallback), _serverSocket);
}

我不明白为什么您不能只使用一个_serverSocket.BeginAccept,为什么不使用十。

没有理由像这样产生几个BeginAccept。只需在BeginAccept中调用一个新的AcceptCallback

问题2 –大约收到零字节

在ReceiveCallback()中,如果我们收到零字节,则关闭连接。为什么?当总是收到零字节时,是否认为客户端已关闭连接?在我这里所做的测试中,当客户端关闭连接时,我收到一个在SocketException中捕获的异常。我在这里想念什么吗?

是。 0字节表示正常断开连接。也就是说,另一端首先使用Shutdown,然后使用Close,而不是直接关闭。

任何其他类型的断开连接都会产生异常。

问题3 –关于是否需要再次开始接收

在套接字中接收到某些内容后,将其放回BeginReceive。为什么我们需要再次开始接收?这不应该自动吗?

没有例如,当您关闭服务器时,您不想再次阅读。其他客户端可能只希望接收一次,处理数据然后断开连接。

问题4 –关于缓冲区大小

使用255个字节的缓冲区。我知道,如果一条消息的长度大于缓冲区的大小,则它将在多个接收中碎片化。我应该设置一个足够大的缓冲区大小以保证没有消息会被碎片化,还是我必须提供代码来处理消息碎片(将多个接收合并到一个缓冲区中)?

一个发送的byte[]总是可以被伪装成多个接收。一个接收也可以包含两个发送的byte[]缓冲区。这就是TCP的工作方式。

您通常使用一个接收缓冲区,然后再使用另一个来构建消息。或者使用更大的缓冲区,并通过在方法调用中使用更大的offset来告诉Receive完成消息。


2
投票

好吧,我去:

© www.soinside.com 2019 - 2024. All rights reserved.