【问题标题】:C# Using tcp and udp protocolsC# 使用 tcp 和 udp 协议
【发布时间】:2017-01-05 14:40:22
【问题描述】:

我需要在我的应用程序中使用 udp 和 tcp 连接,TcpClient/TcpListener 很少处于活动状态,但 udp 将是主要用途。

这是服务器代码:

    static void Main(string[] args)
    {
        TcpListener  listener = new TcpListener(IPAddress.Any, 25655);
        listener.Start();
        Socket  sck = listener.AcceptTcpClient().Client;
        UdpClient udpServer = new UdpClient(1100);
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        var data = udpServer.Receive(ref remoteEP);
        string result = Encoding.UTF8.GetString(data);
        Console.WriteLine(result);
        Console.Read();
    }

这是客户端:

   static void Main(string[] args)
    {
       TcpClient client = new TcpClient("127.0.0.1", 25655);
       Socket sck = client.Client;
       UdpClient udpclient = new UdpClient();
       IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1100); // endpoint where server is listening
       udpclient.Connect(ep);
       byte[] data = UTF8Encoding.UTF8.GetBytes("Hello");
       udpclient.Send(data,data.Length);       
    }

我首先建立 Tcp 连接,然后我尝试连接并将数据从客户端发送到服务器。 从我添加的断点,我可以看到 Tcp 部分正常工作,客户端完成程序但在服务器中,它挂在接收部分 var data = udpServer.Receive(ref remoteEP); 就像没有数据到达..当我删除 tcp 代码部分(从服务器和客户端的前 2 行)它工作得很好,显示结果消息。

有谁知道为什么我无法从客户端获取数据?

提前致谢。

【问题讨论】:

标签: c# sockets tcp network-programming udp


【解决方案1】:

UDP 和 TCP 的主要区别在于 TCP 会尝试重新发送消息,直到服务器告诉客户端它已收到它。即使数据包永远无法到达或主机根本不存在,UDP 也会发送并忘记它

这是您的代码流程

服务器启动 TCP
客户端发送 TCP
服务器接收 TCP
客户端发送 UDP(服务器尚未侦听,数据包丢失但 UDP 不关心)
服务器开始监听 UDP
服务器等待 UDP 到来

您想在尝试从客户端发送消息之前进行一些多线程编程并同时启动它们。

【讨论】:

  • 你的意思是客户端在服务器开始接收之前发送数据?所以如果我在发送部分(在客户端代码中)之前使用Thread.Sleep();,我可以在服务器端读取消息吗?
  • @Slashy 你应该这样做。
【解决方案2】:

如果你先在服务器端启动UDP客户端,然后在客户端和服务器之间建立TCP连接呢?!

服务器

        static void Main(string[] args)
    {
        UdpClient udpServer = new UdpClient(1100);
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);

        TcpListener listener = new TcpListener(IPAddress.Any, 25655);
        listener.Start();
        Socket sck = listener.AcceptTcpClient().Client;

        var data = udpServer.Receive(ref remoteEP);
        string result = Encoding.UTF8.GetString(data);
        Console.WriteLine(result);
        Console.Read();
    }

客户

static void Main(string[] args)
{
    TcpClient client = new TcpClient();
    client.Connect("127.0.0.1", 25655);

    UdpClient udpclient = new UdpClient();
    IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1100); // endpoint where server is listening
    udpclient.Connect(ep);
    byte[] data = UTF8Encoding.UTF8.GetBytes("Hello");
    udpclient.Send(data, data.Length);
}

【讨论】:

    【解决方案3】:

    问题是listener.AcceptTcpClient()blocks your current thread 和服务器端的 UdpClient 在创建 Tcp 连接之前没有建立。实际上,您的服务器正在等待 Tcp 连接,然后才开始侦听 Udp 连接,而您的客户端则一一创建了 2 个连接。我的建议是 - 您的服务器在客户端实际发送数据后开始监听 Udp 端口​​。检查我的建议的最简单方法 - 对于客户端代码,在通过 UDP 发送数据之前添加 Thread.Sleep(1000)。为了使其正常工作,您可能需要修改代码而不阻塞主线程,而是以类似于以下方式分离 Tcp 和 Udp:

    static void Main(string[] args)
    {
        Task.Factory.StartNew(() => 
        {
            TcpListener listener = new TcpListener(IPAddress.Any, 25655);
            listener.Start();
            Socket sck = listener.AcceptTcpClient().Client;
    
            // ToDo: further actions related to TCP client
        }, TaskCreationOptions.LongRunning);
    
        UdpClient udpServer = new UdpClient(1100);
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
        var data = udpServer.Receive(ref remoteEP);
        string result = Encoding.UTF8.GetString(data);
        Console.WriteLine(result);
        Console.Read();
    }
    

    本例中客户端代码可能保持不变,但对于实际项目,我建议也将其分开,以确保您希望通过 Tcp 从服务器取回一些数据。

    【讨论】:

      猜你喜欢
      • 2013-10-05
      • 2022-01-20
      • 2022-08-23
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      相关资源
      最近更新 更多