首页 文章

UDP套接字:远程主机强制关闭现有连接

提问于
浏览
0

我对UDP套接字相当新,我的大多数套接字经验都是使用TCP .

我正在使用C#创建UDP套接字,绑定它然后不断监听来自IP的数据包 . 但是,当客户端发送数据包时,套接字会抛出异常:“远程主机强行关闭现有连接” .

这是我创建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

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

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

newClient.remoteEndpoint 来自TCP套接字的 endpoints ,因此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 已关闭”没有意义 . 我在这里做错了吗?

1 回答

  • 0

    BeginReceiveFrom 中,您的remoteEP应该识别正在侦听的套接字,主要是您用于 Bind 的相同 endpoints .

    在你的回调方法 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 的 endpoints 相同 .

相关问题