2017-10-23 18 views
0

私は今まで数時間執着してきたが、今まではやっていない。 Googleのトンと研究のトンがまだストレートではありません。C#ソケット(TCPとUDP)

私はクライアントと、完全に機能する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..."); 
     } 
    } 
} 
+1

は、私は右のあなたが一緒にUDPクライアントとサーバーの作業を行うことができないことを理解しているだろうか? –

+2

私の知るところでは、同じポート上でTCPとUDPを同時に受信することはできません。一般に、ポート上で実行できるプロトコルは1つだけです。例:リッスンと送信のためのあなたのUDPポート番号、それは動作するはずです。 – KBO

+0

@KBOポートフォワーディングルールを見ると "Both"というオプションが許可されるので、私はUDPとTCPに単一のポートを使うことができるという仮定をしているので、わからなかった。 –

答えて

1

同じポートで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(); 
    } 
    } 
} 
+0

これは、UDPを特定のクライアントに割り当てることができないということです。 –

+0

私はいくつかの実験をすることをお勧めします。例えばUDPデータグラムが実際に送信されているかどうかを確認するためにWiresharkを使用します。 'UdpClient.Connect'コールがなければ、' UdpClient.Receive'コールから返されたリモートエンドポイントを使って、不要なリモートクライアントをチェック/スキップすることができます。許可されたリモートクライアントは、受け入れられたTCPソケット接続などに格納できます。 – KBO