TcpListener请求泛洪

时间:2017-06-06 18:05:24

标签: .net c#-4.0 tcp tcpclient tcplistener

大家好:我正在努力确保我的TcpListener能够正确处理来自客户端的多个请求。我在for循环中尝试多个BeginSend方法调用,并发现Listener的输出在我获得的响应数方面不一致。即如果我按顺序调用BeginSend 20次,我希望听众给我20个回复。有时我会得到2,有时是3,有时甚至更多,而且看起来,我发送给监听器的消息会相互附加,而不是被视为单独的实体。

假设我有一个有效的TcpClient类(请参阅代码),它包装了一个基本的TcpClient和一个有效的TcpListener类(请参阅代码),它通过以接收到的消息为参数引发DataReceived事件来响应来自连接的TcpClient的消息。非常基本的代码

for(int i = 0; i < 10; i++)
{
    client.Client.BeginSend(Encoding.ASCII.GetBytes(i.ToString()), 0, i.ToString().Length, SocketFlags.None, null, null);
}

我希望TcpListener的输出为
0
1
...
9个

相反,我得到的结论是: 0
123456789个
或者,
0
1234
56个
789个
或者,
....
或者10个单独消息的其他一些排列 以下是Listener的相关代码:

    private void ListenForNewClients()
    {
        Task.Run(async () =>
        {
            while (true)
            {
                var tcpClient = await tcpServer.AcceptTcpClientAsync();

                clients.Add(tcpClient.Client);
                tcpClient.Client.BeginReceive(buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, tcpClient.Client);

            }
        });
    }

和ReceiveCallback:

    private void ReceiveCallback(IAsyncResult ar)
    {
        var tcpClient = ar.AsyncState as Socket;
        try
        {
            var bytesRead = tcpClient.EndReceive(ar);

            if (bytesRead == 0)
            {
                tcpClient.EndReceive(ar);
            }

            var data = Encoding.ASCII.GetString(buffer, 0, bytesRead);

            DataReceived?.Invoke(this, data);

            buffer = new byte[BufferSize];
            tcpClient.BeginReceive(buffer, 0, BufferSize, SocketFlags.None, ReceiveCallback, tcpClient);

        }
        catch
        {
            clients.Remove(tcpClient);
        }
    }

1 个答案:

答案 0 :(得分:1)

  

看来,我发送给监听器的消息将被附加到彼此,而不是被视为单独的实体。

这就是TCP / IP的工作原理。

如果您同时编写客户端和服务器,那么我建议使用SignalR,它会保留消息边界。

如果必须使用TCP / IP,那么您需要某种形式的message framing