我正在使用以下代码(根据之前关于SO的问题的答案构建):
public void Start()
{
listener = new TcpListener(IPAddress.Any, 9030);
listener.Start();
Console.WriteLine("Listening...");
StartAccept();
}
private void StartAccept()
{
listener.BeginAcceptTcpClient(HandleAsyncConnection, listener);
}
private void HandleAsyncConnection(IAsyncResult res)
{
StartAccept();
TcpClient client = listener.EndAcceptTcpClient(res);
StringBuilder sb = new StringBuilder();
var data = new byte[client.ReceiveBufferSize];
using (NetworkStream ns = client.GetStream())
{
int readCount;
while ((readCount = ns.Read(data, 0, client.ReceiveBufferSize)) != 0)
{
sb.Append(Encoding.UTF8.GetString(data, 0, readCount));
}
// Do work
// Test reply
Byte[] replyData = System.Text.Encoding.ASCII.GetBytes(DateTime.Now.ToString());
ns.Write(replyData, 0, replyData.Length);
ns.Flush();
ns.Close();
}
client.Close();
}
“Do work”行代表我将为客户端执行所需处理的位置。
但是,我看不到如何使用此代码读取客户端的数据,然后回复它。使用此代码时,我可以完美地读取客户端发送的内容,但是一旦发生这种情况,客户端就会锁定并最终抱怨连接已终止。它没有收到我的回复。
有关如何解决此问题的任何想法?
答案 0 :(得分:1)
好的,首先,您要混合异步调用(BeginAcceptTcpClient
)和同步(Read
和Write
)调用。这完全杀死了异步代码的目的。第二,也许这就是你的套接字关闭的原因?在异步套接字上执行同步操作。我不确定,但没有客户端代码就无法分辨。
无论如何,这不是你如何构建一个异步的多客户端服务器。
这是一个完全异步的服务器实现:http://msdn.microsoft.com/en-us/library/fx6588te.aspx
答案 1 :(得分:0)
我认为您应该使用长度字节来分配缓冲区。 ReceiveBufferSize可以多次调用,我认为没有保证你在一个区块内收到所有东西。
答案 2 :(得分:0)
您误解了Read
的工作原理。它会阻塞,直到从另一个端点收到某些东西。它返回0的唯一时间是另一方断开连接,因此您将继续读取,直到另一侧断开连接。
使用TCP时,您需要知道消息何时结束。您可以通过首先将消息长度作为标题发送,或者在每条消息后使用后缀(作为换行符)来实现。然后你应该继续阅读,直到完整的信息到达。