2014-11-12 2 views
1

다중 스레드 UDP 클라이언트/서버를 가져 오려고하지만 서버 측에서 문제가 발생합니다. 클라이언트가 등록을 시도하면 스레드가 생성되고 해당 클라이언트의 모든 상호 작용이 해당 스레드에서 처리되지만 몇 가지 이유로 스레드를 한 번 입력 한 다음 즉시 종료됩니다. 왜 이런 일이 발생하는지 파악하는 데 도움이 될 수 있습니까? 사전에 고마워요 ..다중 스레드 UDP 클라이언트/서버 C#

namespace AuctionServer 
{ 
    class Program 
    { 
    public static Hashtable clientsList = new Hashtable(); 

    static void Main(string[] args) 
    { 
     //IPAddress ipAd = IPAddress.Parse("255.255.255.255"); 
     UdpClient server = new UdpClient(8888); 
     IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0); 
     string data = ""; 
     int listSize = 0; 
     Console.WriteLine("Auction Server Started ...."); 
     listSize = clientsList.Count; 

     while (true) 
     { 
      //Reads data 
      byte[] inStream = server.Receive(ref remoteEndPoint); 
      data = Encoding.ASCII.GetString(inStream); 
      //Console.WriteLine("REGISTER " + remoteEndPoint); 

      if (!data.Contains("DEREGISTER ")) 
      { 
       byte[] sendBytes = Encoding.ASCII.GetBytes(data + remoteEndPoint.ToString()); 
       server.Send(sendBytes, sendBytes.Length, remoteEndPoint); 
       handleClinet client = new handleClinet(); 
       Console.WriteLine(data); 
       clientsList.Add(data, server); 
       client.startClient(server, data, clientsList, remoteEndPoint); 
       data = ""; 
      } 
     } 
    } 

    //Broadcast method is used to send message to ALL clients 
    public static void broadcast(UdpClient dest, string msg, string uName, bool flag, IPEndPoint sendEP, Hashtable clientsList) 
    { 
     foreach (DictionaryEntry Item in clientsList) 
     { 
      Byte[] broadcastBytes = null; 

      if (flag == true) 
      { 
       broadcastBytes = Encoding.ASCII.GetBytes(msg); 
      } 
      else 
      { 
       broadcastBytes = Encoding.ASCII.GetBytes(msg); 
      } 
      dest.Send(broadcastBytes, broadcastBytes.Length, sendEP); 

     } 
    } 
}//end Main class 

}

namespace AuctionServer 
{ 
public class handleClinet 
{ 
    UdpClient clientSocket; 
    string clNo; 
    Hashtable clientsList; 
    IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0); 
    IPEndPoint myEP = new IPEndPoint(IPAddress.Any, 0); 

    public void startClient(UdpClient inClientSocket, string clineNo, Hashtable cList, IPEndPoint tempEP) 
    { 
     this.myEP = tempEP; 
     this.clientSocket = inClientSocket; 
     this.clNo = clineNo; 
     this.clientsList = cList; 
     Thread ctThread = new Thread(doChat); 
     ctThread.Start(); 
    } 

    private void doChat() 
    { 
     int requestCount = 0; 
     byte[] bytesFrom = new byte[10025]; 
     string dataFromClient = null; 
     string rCount = null; 
     requestCount = 0; 

     while ((true)) 
     { 
      try 
      { 
       //Thread.Sleep(1000); 
       if (requestCount == 0) 
       { 
        Console.WriteLine("Thread Created"); 
        requestCount++; 
       } 
       byte[] received = clientSocket.Receive(ref remoteIPEndPoint); 
       dataFromClient = Encoding.ASCII.GetString(received); 
       Console.WriteLine(dataFromClient); 

       if (dataFromClient.Contains("DEREGISTER")) 
        clientSocket.Send(received, received.Length, remoteIPEndPoint); 
        //Program.broadcast(clientSocket, "DREG-CONF", clNo, true, myEP, clientsList); 
       //else 
       // Program.broadcast(clientSocket, dataFromClient, clNo, true, myEP, clientsList); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
       Console.ReadKey(); 
       break; 
      } 
     }//end while 
    }//end doChat 

}

+1

Console.WriteLine (ex.ToString());에서 예외가 발생하고 있습니까? –

+0

예외가 발생하지 않으면 코드는 계속 while 루프에있는 while 루프 대신 Program.cs에 걸렸습니다. @MarkSegal – philr

답변

1

두 개의 루프는 다른 스레드에서 실행됩니다. 따라서 handleClinet 클래스의 루프와 함께 Main()의 루프가 동시에 실행 중입니다. 로 전환 - 당신이 handleClinet 클래스의 루프 및 디버그 그것을 전환 할 경우

후 디버거에서 Threads 창 사용 (D, TDebug 메뉴, Windows 메뉴 항목, 다음 Threads을 ... 또는 Ctrl를 누름) 그 스레드. 그런 다음 호출 스택과 그 스레드의 상태를 볼 수 있습니다.

Visual Studio의 Express 버전에서는 작동하지 않을 수 있습니다. 나는 가장 최근 버전을 시도하지 않았지만, 이전 버전은 Threads 창을 지원하지 않았습니다. (중단 점을 & hellip으로 설정하여 특정 스레드를 디버깅 할 수 있으며 스레드로 수동 전환 할 수 없습니다.

+0

디버깅을했는데 문제를 파악하지 못하는 것 같습니다. 클라이언트가 서버에 "등록"명령을 보내면 서버는 해당 클라이언트에 대한 스레드를 만들고 그 스레드에서 통신을 처리하기를 원합니다. 이것이 가능한가? @PeterDuniho – philr

+0

어떤 스레드가 실행 중인지에 대한 질문과 관련이 있는지는 알 수 없습니다. 그러나 아니요, 스레드가 다른 스레드에서 사용되는 동일한 소켓을 사용하는 경우가 아닙니다. 앞의 질문에 대해 설명했듯이 동일한 소켓에서 두 개의 다른 스레드를 읽는다면 어떤 스레드가 어떤 메시지를 읽는지 제어 할 방법이 없습니다. –

+0

난 그냥 스레드 메뉴를 사용하여 디버깅 및 중단 점을 넣고 F10 코드를 사용하여 다음 문을 검사 할 때 코드가 잘 작동하는 것처럼 보입니다. 그러나 중단 점을 제거하고 코드를 정상적으로 실행하면 정상적으로 작동하지 않습니다. 이 이유를 생각해 볼 수 있습니까? @PeterDuniho 그런데 당신의 도움에 감사합니다 – philr