UDP Socket:一个现有的连接被远程主机强行关闭

Posted

技术标签:

【中文标题】UDP Socket:一个现有的连接被远程主机强行关闭【英文标题】:UDP Socket: An existing connection was forcibly closed by the remote host 【发布时间】:2013-09-02 15:57:05 【问题描述】:

我对 UDP 套接字相当陌生,我的大部分套接字经验都是使用 TCP。

我正在使用 C# 创建一个 UDP 套接字,绑定它,然后不断地侦听来自 IP 的数据包。但是,当客户端发送数据包时,socket 会抛出异常:“An existing connection was forced by the remote host”。

这就是我创建 UDP 套接字的方式:

Socket UDPSocket = new Socket(SocketType.Dgram, ProtocolType.Udp); //Create UDP socket
UDPSocket.Bind(new IPEndPoint(IPAddress.Any, 1338)); //Bind port 1338 from any IP

创建socket后,我异步接收数据:

UDPSocket.BeginReceiveFrom(newClient.bufferu, 0, AbstractServerClient.BUFFER_SIZE, 0, ref newClient.remoteEndpoint,new AsyncCallback(ReceiveCallbackUDP), newClient);

newClient.remoteEndpoint 来自 TCP 套接字的端点,因此 UDP 有效地接收来自与 TCP 连接的同一 IP 的数据包。假设其余参数有效(它们在 TCP 上工作正常)。

ReceiveCallbackUDP 方法如下所示:

public void ReceiveCallbackUDP(IAsyncResult ar)

    AbstractServerClient client = (AbstractServerClient)ar.AsyncState;
    int bytesRead = UDPSocket.EndReceive(ar);

    if (bytesRead > 0)
    
        Bitstream data = new Bitstream(client.bufferu, 12);
        int bytesProcessed = 12;
        while (bytesProcessed < bytesRead)
        
            ushort messageLength = data.ReadUInt16(); //Read the message length
            byte messageID = data.ReadByte(); //Read the message ID
            // Logger.Log("Received message ID: " + messageID.ToString() + " (Size: " + messageLength + " bytes)");
            bytesProcessed += messageLength + sizeof(UInt16);
            client.GetPacketHandler(messageID).HandlePacket(data); //Process the message
            bytesProcessed += 12;
            data.Seek(bytesProcessed); //Seek to the next message
        
    
    UDPSocket.BeginReceiveFrom(client.bufferu, 0, AbstractServerClient.BUFFER_SIZE, 0, ref client.remoteEndpoint, new AsyncCallback(ReceiveCallbackUDP), client);

该函数在套接字上调用EndReceive() 来读取数据,并对其进行处理,并调用BeginReceiveFrom 以等待更多数据(异步)。在int bytesRead = UDPSocket.EndReceive(ar);这一行抛出异常

为什么会这样?据我了解,UDP 是一个无连接套接字,因此“现有 connection 已关闭”异常没有意义。我在这里做错了吗?

【问题讨论】:

您可能遇到了与此处提到的相同的问题:***.com/questions/7201862/… 【参考方案1】:

BeginReceiveFrom 中,您的remoteEP 应该标识正在侦听的套接字,大部分与您用于Bind 的端点相同。

在你的回调方法ReceiveCallbackUDP中你应该调用EndReceiveFrom,因为这是BeginReceiveFrom的对应方法:

EndPoint tempRemoteEP = (EndPoint)client.remoteEndpoint;
int bytesRead = UDPSocket.EndReceiveFrom(ar, ref tempRemoteEP);

参见http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.beginreceivefrom.aspx 中的示例,其中tempRemoteEP 传递给BeginReceiveFromsender 传递给Bind 的端点相同。

【讨论】:

以上是关于UDP Socket:一个现有的连接被远程主机强行关闭的主要内容,如果未能解决你的问题,请参考以下文章

C# HttpClient 一个现有的连接被远程主机强行关闭

.Net 核心 HttpClient 错误? SocketException:一个现有的连接被远程主机强行关闭

java.io.IOException: 远程主机强迫关闭了一个现有的连接。

现有连接被远程主机强行关闭

UDP错误10054:远程主机强迫关闭了一个现有的连接

python 远程主机强迫关闭了一个现有的连接 socket 超时设置 errno 10054