c# udp套接字通信-每个套接字地址(协议/网络地址/端口)通常只允许使用一次

本文关键字:套接字 许使用 一次 udp 端口 地址 协议 网络地址 通信 | 更新日期: 2023-09-27 18:14:07

我想做两个应用程序。一个将发送数据到特定的udp端口,另一个将读取它。

我有两个问题:

  1. 在同一台机器上运行时,我得到一个错误:"只有一次使用每个套接字的地址(协议/网络地址/端口)是正常的permitted"所以我需要想办法在我没有的情况下测试它
  2. 当我尝试使用我的网络中另一台电脑的内部ip,我没有得到
服务器:

private Socket sock;
private const int PORT = 5000;
public void start()
{
        sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        sock.ReceiveTimeout = 1;// seconds
        sock.SendTimeout = 1;// seconds
        IPEndPoint iep = new IPEndPoint(IPAddress.Any, PORT);
        EndPoint ep = (EndPoint)iep;
        sock.Bind(iep);
        MulticastView view_obj = new MulticastView();
        while(true)
        {
            try
            {
                if (sock.Connected)
                {
                    sock.Send(Serializer.ObjectToByteArray(view_obj));
                }
            }catch(Exception ex){
                Console.WriteLine(ex);
            }
            Thread.Sleep(1000); // milliseconds
        }
}
客户:

        IPAddress ip = IPAddress.Parse("127.0.0.1");
        IPEndPoint iep = new IPEndPoint(ip, PORT);
        EndPoint ep = (EndPoint)iep;
        UdpClient client = new UdpClient(PORT);
        IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
        // or using: Byte[] receiveBytes = client.Receive(ref ep); 
        Byte[] receiveBytes = client.Receive(ref RemoteIpEndPoint); 
        MulticastView view;
        view = (MulticastView)Serializer.ByteArrayToObject(receiveBytes);

请注意,我需要单独的应用程序(在单独的进程)。

c# udp套接字通信-每个套接字地址(协议/网络地址/端口)通常只允许使用一次

尽管这是一个老问题,但我认为指出一个端口规则的例外是很好的。

如果您正在使用多播(这是UDP到多播地址),您可以设置SO_REUSEADDR选项以使用多个套接字的端口。

你不能在同一个IP地址/端口上打开2个独立的套接字。可以说,每个IP/端口都是一个唯一的邮箱。(从技术上讲,在某些情况下,可以将2个进程附加到同一个套接字,但这与您的问题无关)。这个规则很简单,但是有几种变通方法。

我会问客户端是否真的需要一个标准端口号。通常,UDP/TCP客户端只使用随机套接字并与服务器通信。服务器通常是连接中唯一需要标准的固定端口的一方。UdpClient.Receive()方法将使用数据包发送方的ip/端口填充IPEndPoint,以便您可以对其进行回复。

要么不绑定IPAddress。Any(导致它绑定到所有接口)。将Any替换为特定的IP地址(如果设置IP别名或多个适配器,一台机器可以有多个),或者更简单,将客户机的端口号更改为不同于服务器的端口号。您应该能够将一端绑定到主以太网接口IP地址,并将客户端绑定到环回(127.0.0.1)地址。