【问题标题】:When to close a UDP socket何时关闭 UDP 套接字
【发布时间】:2013-11-18 03:40:36
【问题描述】:

我有一个客户端-服务器应用程序,它使用 UDP 套接字发送数据,数据只需从客户端传输到服务器,服务器将始终具有相同的 IP。唯一的要求是我必须每秒发送大约 10 条消息

目前我正在这样做:

public void SendData(byte[] packet)
{
    IPEndPoint end_point = new IPEndPoint(serverIP, serverPort);
    UdpClient udpChannel = new UdpClient(sourcePort);
    udpChannel.Connect(end_point);
    udpChannel.Send(packet, packet.Length);
    udpChannel.Close();
}

我遇到的问题是,当我使用命令“udpChannel.Close()”时,服务器未在监听时需要 2-3 秒才能执行。 (我在What is the drawback if I do not invoke the UdpClient.Close() method? 看到过同样的问题)

我的问题是,如果我总是将数据包发送到相同的 IP 地址和端口,是否有必要在每次发送请求后连接套接字并关闭它?

我打算使用的代码如下:

UdpClient udpChannel;

public void SendData(byte[] packet)
{
    udpChannel.Send(packet, packet.Length);
}

public void Initialize(IPAddress IP, int port)
{
    IPEndPoint end_point = new IPEndPoint(serverIP, serverPort);
    UdpClient udpChannel = new UdpClient(sourcePort);
    udpChannel.Connect(end_point);
}

public void Exit()
{
    udpChannel.Close();
}

这样做,是否有必要在发送数据之前对“SendData”方法进行一些检查? 上面的代码有问题吗?

谢谢!

【问题讨论】:

    标签: c# sockets udp


    【解决方案1】:

    UDP 是无连接的,调用 udpChannel.Connect 仅指定一个默认主机端点以用于 Send 方法。您无需在发送之间关闭客户端,将其保持打开状态不会让任何连接或侦听器在发送之间运行。

    【讨论】:

      【解决方案2】:

      您不应在每次发送请求后连接/关闭。当您开始工作时 - 您连接到套接字。你可以发送数据。当您不想发送/接收数据时,您应该关闭 UdpClient,例如当您关闭表单时。

      在您的情况下,您可以在关闭/发送客户端时检查udpClient != null,您可以使用try/catch,例如:

      try
      {
          udpClient.Send(sendBytes, sendBytes.Length);
      }
      catch (Exception exc)
      {
          // handle the error
      }
      

      连接时使用 try/catch,因为端口可能正忙或其他连接问题。 看看UdpClient.SendAsync :)

      【讨论】:

        【解决方案3】:
        using System.Collections;
        using System.Collections.Generic;
        using UnityEngine;
        using UnityEngine.Networking;
        using System.Text;
        using System.Net.Sockets;
        using System;
        using System.Net;
        
        public class Server : MonoBehaviour
        {
            //int[] ports;
            UdpClient udp; // Udp client
        
            private void Start()
            {
                udp = new UdpClient(1234);
                udp.BeginReceive(Receive, null);
            }
        
            void Send(string msg, IPEndPoint ipe)
            {
                UdpClient sC = new UdpClient(0);
                byte[] m = Encoding.Unicode.GetBytes(msg);
                sC.Send(m, msg.Length * sizeof(char), ipe);
                Debug.Log("Sending: " + msg);
                sC.Close();
            }
        
            void Receive(IAsyncResult ar)
            {
                IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 0);
                byte[] data = udp.EndReceive(ar, ref ipe);
                string msg = Encoding.Unicode.GetString(data);
                Debug.Log("Receiving: " + msg);
        
                udp.BeginReceive(Receive, null);
            }
        }
        

        在 Send() 中,我使用新的 UDP 客户端并在每次之后关闭它。更好的是,你可以同时发送和接收。

        【讨论】:

        • 这不是更好。情况更糟。您冒着无法再次获得相同端口号的相当大的风险,并且在套接字关闭时到达的所有数据都将丢失。保持打开状态。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        • 2013-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-19
        • 2011-02-15
        相关资源
        最近更新 更多