2017-10-23 1 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 수신 대기를 동시에 실행할 수 없습니다. 일반적으로 포트에서 하나의 프로토콜 만 실행할 수 있습니다. 예 : 변경 청취 및 전송을위한 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

몇 가지 실험을하는 것이 좋습니다. 예 : Wireshark를 사용하여 UDP 데이터 그램이 실제로 전송되는지 여부를 확인합니다. 'UdpClient.Connect' 호출이 없으면'UdpClient.Receive' 호출에서 반환 된 원격 엔드 포인트를 사용하여 원하지 않는 원격 클라이언트를 검사/건너 뛸 수 있습니다. 허용 된 원격 클라이언트를 허용 된 TCP 소켓 연결 등에 저장할 수 있습니다. – KBO