c# - C#套接字(TCP和UDP)

标签 c# sockets c#-4.0 tcp udpclient

我要直言不讳,我已经坚持了几个小时。谷歌的吨和大量的研究,但到目前为止还没有直接的答案。

我有一个客户端和一个为TCP编码的服务器,它们的功能都很好,但是,我希望该客户端也能够将UDP与服务器一起用于不重要的数据包,例如播放器位置。

截至目前,这是我已连接客户端的连接代码。

public void ConnectToServer(){
    tcp_client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
    tcp_client.Connect(server_ip, server_port);
    tcp_stream = new NetworkStream(this.tcp_client);

    this.udp_client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    this.udp_client.BeginConnect(IPAddress.Parse(server_ip), server_port,new AsyncCallback(udp_connected), null);
}

现在,客户端不是我遇到的问题,因为当我使用udp.Send(byteArray)时,它似乎正在发送,因为它没有引发任何异常,但是服务器本身没有响应收到的任何数据。

请注意,这不是100%复制/粘贴的代码。更改以仅显示问题所在。
private Socket c;
private UdpClient udp;
private isRunning = true;

public Client(Socket c){
    // This was accepted from TcpListener on Main Server Thread.
    this.c = c;
    this.networkStream = new NetworkStream(this.c);

    udp = new UdpClient();
    udp.Connect((IPEndPoint)c.RemoteEndPoint);

    // Then starts 2 thread for listening, 1 for TCP and 1 for UDP.
}

private void handleUDPTraffic(){
    IPEndPoint groupEP = (IPEndPoint)c.RemoteEndPoint;
    while (isRunning){
        try{
            byte[] udp_received = udp.Receive(ref groupEP);
            Console.WriteLine("Received UDP Packet Data: " + udp_received.Length);
        }catch{
            log.ERROR("UDP", "Couldn't Receive Data...");
        }
    }
}

最佳答案

您可以在同一端口上同时使用TCP和UDP。也可以看看:

Can TCP and UDP sockets use the same port?

下面的示例演示,您可以同时发送和接收UDP和TCP消息。

也许,您的UdpClient创建用于监听传入的数据报是问题所在。我建议像TcpListener一样一次创建它。

服务器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TCPUDPServer
{
  class Program
  {
    static void Main(string[] args)
    {
      TcpListener tcpServer = null;
      UdpClient   udpServer = null;
      int         port      = 59567;

      Console.WriteLine(string.Format("Starting TCP and UDP servers on port {0}...", port));

      try
      {
        udpServer = new UdpClient(port);
        tcpServer = new TcpListener(IPAddress.Any, port);

        var udpThread          = new Thread(new ParameterizedThreadStart(UDPServerProc));
        udpThread.IsBackground = true;
        udpThread.Name         = "UDP server thread";
        udpThread.Start(udpServer);

        var tcpThread          = new Thread(new ParameterizedThreadStart(TCPServerProc));
        tcpThread.IsBackground = true;
        tcpThread.Name         = "TCP server thread";
        tcpThread.Start(tcpServer);

        Console.WriteLine("Press <ENTER> to stop the servers.");
        Console.ReadLine();
      }
      catch (Exception ex)
      {
        Console.WriteLine("Main exception: " + ex);
      }
      finally
      {
        if (udpServer != null)
          udpServer.Close();

        if (tcpServer != null)
          tcpServer.Stop();
      }

      Console.WriteLine("Press <ENTER> to exit.");
      Console.ReadLine();
    }

    private static void UDPServerProc(object arg)
    {
      Console.WriteLine("UDP server thread started");

      try
      {
        UdpClient server = (UdpClient)arg;
        IPEndPoint remoteEP;
        byte[] buffer;

        for(;;)
        {
          remoteEP = null;
          buffer   = server.Receive(ref remoteEP);

          if (buffer != null && buffer.Length > 0)
          {
            Console.WriteLine("UDP: " + Encoding.ASCII.GetString(buffer));
          }
        }
      }
      catch (SocketException ex)
      {
        if(ex.ErrorCode != 10004) // unexpected
          Console.WriteLine("UDPServerProc exception: " + ex);
      }
      catch (Exception ex)
      {
        Console.WriteLine("UDPServerProc exception: " + ex);
      }

      Console.WriteLine("UDP server thread finished");
    }

    private static void TCPServerProc(object arg)
    {
      Console.WriteLine("TCP server thread started");

      try
      {
        TcpListener server = (TcpListener)arg;
        byte[]      buffer = new byte[2048];
        int         count; 

        server.Start();

        for(;;)
        {
          TcpClient client = server.AcceptTcpClient();

          using (var stream = client.GetStream())
          {
            while ((count = stream.Read(buffer, 0, buffer.Length)) != 0)
            {
              Console.WriteLine("TCP: " + Encoding.ASCII.GetString(buffer, 0, count));
            }
          }
          client.Close();
        }
      }
      catch (SocketException ex)
      {
        if (ex.ErrorCode != 10004) // unexpected
          Console.WriteLine("TCPServerProc exception: " + ex);
      }
      catch (Exception ex)
      {
        Console.WriteLine("TCPServerProc exception: " + ex);
      }

      Console.WriteLine("TCP server thread finished");
    }
  }
}

客户:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace TCPUDPClient
{
  class Program
  {
    static void Main(string[] args)
    {
      UdpClient      udpClient = null;
      TcpClient      tcpClient = null;
      NetworkStream  tcpStream = null;
      int            port      = 59567;
      ConsoleKeyInfo key;
      bool           run = true;
      byte[]         buffer;

      Console.WriteLine(string.Format("Starting TCP and UDP clients on port {0}...", port));

      try
      {
        udpClient = new UdpClient();
        udpClient.Connect(IPAddress.Loopback, port);

        tcpClient = new TcpClient();
        tcpClient.Connect(IPAddress.Loopback, port);

        while(run)
        {
          Console.WriteLine("Press 'T' for TCP sending, 'U' for UDP sending or 'X' to exit.");
          key = Console.ReadKey(true);

          switch (key.Key)
          {
            case ConsoleKey.X:
              run = false;
              break;

            case ConsoleKey.U:
              buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));
              udpClient.Send(buffer, buffer.Length);
              break;

            case ConsoleKey.T:
              buffer = Encoding.ASCII.GetBytes(DateTime.Now.ToString("HH:mm:ss.fff"));

              if (tcpStream == null)
                tcpStream = tcpClient.GetStream();

              tcpStream.Write(buffer, 0, buffer.Length);
            break;
          }
        }
      }
      catch (Exception ex)
      {
        Console.WriteLine("Main exception: " + ex);
      }
      finally
      { 
        if(udpClient != null)
          udpClient.Close();

        if(tcpStream != null)
          tcpStream.Close();

        if(tcpClient != null)
          tcpClient.Close();
      }

      Console.WriteLine("Press <ENTER> to exit.");
      Console.ReadLine();
    }
  }
}

关于c# - C#套接字(TCP和UDP),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46882815/

相关文章:

c# - 根据类型调用DAL方法

c# - 如果模型未实现 INotifyPropertyChanged, View 模型如何从其底层模型传播更改通知?

linq - MongoDb c# driver LINQ vs Native 查询

c#-4.0 - 在加载C#时将嵌入式资源.rtf文件加载到richtextbox中

sockets - 代理服务器如何与 tcp/http 连接一起工作?

c# - 向WCF添加服务引用(失败)

javascript - 如何使用 javascript 调用 UserControl 中的函数(代码隐藏)

c# - 流的通用 IDisposable 包装器 - 捕获所有异常的替代方法

node.js - 无法连接安全的 websocket

java - ReadableByteChannel.read()为什么会出现IOExceptions