我是一个相当新的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套接字的端点,因此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是一个无连接套接字,因此“现有连接已关闭”的例外情况没有意义。我在这里做错了吗?
答案 0 :(得分:0)
在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
的{{1}}与传递给BeginReceiveFrom
的{{1}}的端点相同。