c#套接字读取数据然后回复

时间:2011-04-21 14:52:46

标签: c# sockets tcp

我正在使用以下代码(根据之前关于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”行代表我将为客户端执行所需处理的位置。

但是,我看不到如何使用此代码读取客户端的数据,然后回复它。使用此代码时,我可以完美地读取客户端发送的内容,但是一旦发生这种情况,客户端就会锁定并最终抱怨连接已终止。它没有收到我的回复。

有关如何解决此问题的任何想法?

3 个答案:

答案 0 :(得分:1)

好的,首先,您要混合异步调用(BeginAcceptTcpClient)和同步(ReadWrite)调用。这完全杀死了异步代码的目的。第二,也许这就是你的套接字关闭的原因?在异步套接字上执行同步操作。我不确定,但没有客户端代码就无法分辨。

无论如何,这不是你如何构建一个异步的多客户端服务器。

这是一个完全异步的服务器实现:http://msdn.microsoft.com/en-us/library/fx6588te.aspx

答案 1 :(得分:0)

我认为您应该使用长度字节来分配缓冲区。 ReceiveBufferSize可以多次调用,我认为没有保证你在一个区块内收到所有东西。

答案 2 :(得分:0)

您误解了Read的工作原理。它会阻塞,直到从另一个端点收到某些东西。它返回0的唯一时间是另一方断开连接,因此您将继续读取,直到另一侧断开连接。

使用TCP时,您需要知道消息何时结束。您可以通过首先将消息长度作为标题发送,或者在每条消息后使用后缀(作为换行符)来实现。然后你应该继续阅读,直到完整的信息到达。