2016-08-30 3 views
-1

私はうまく動作するUDPサーバー/クライアントプログラムを持っています。UDPサーバー、出力は各ループの後に倍増

1つのクライアントから受け取ったメッセージを、接続されているすべてのクライアントに送り返しますが、各ループの後に出力が倍になります。 クライアントでListArrayをリセットする必要があると思いますが、最初のメッセージのみがSendになります。

誰かが考えていますか?ありがとう!

UDPサーバ

//Listening on Port 12222 
    int servPort = 12222; 

    UdpClient client = null; 

    //Create a new ListArray for the connected Clients 
    ArrayList IPArray = new ArrayList(); 

    try 
    { 
     //Create an instance of UdpClient 
     client = new UdpClient(servPort); 
    } 
    catch (SocketException se) 
    { 
     Console.WriteLine(se.ErrorCode + ": " + se.Message); 
     Environment.Exit(se.ErrorCode); 
    } 

    //Create an new IPEndPoint 
    IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0); 


    //Endless loop 
    for (; ;) 
    { 
     try 
     { 
      //Receive a byte array with contents 
      byte[] byteBuffer = client.Receive(ref remoteIPEndPoint); 

      //Message from Client 
      string returnData = Encoding.ASCII.GetString(byteBuffer); 

      //Add connected Client IPs to ListArray 
      IPArray.Add(remoteIPEndPoint); 

      //Send the received Message back to all Clients in the ArrayList 
      for (int i = 0; i < IPArray.Count; i++) 
      { 
       Console.WriteLine("Handling client at " + IPArray[i] + " - " + returnData + " arraylist.Length " + IPArray.Count + "\n"); 

       Byte[] sendBytes = Encoding.ASCII.GetBytes("Clients Send " + returnData + "\n"); 
       client.Send(sendBytes, sendBytes.Length, (IPEndPoint)IPArray[i]); 
      } 

      Console.WriteLine("echoed {0} bytes.", byteBuffer.Length); 
     } 
     catch (SocketException se) 
     { 
      Console.WriteLine(se.ErrorCode + ": " + se.Message); 
     } 
    } 
} 

UDPのCLIENT

//Server name or IP address 
static String server = "127.0.0.1";  

//Port 
static int servPort = 12222; 

//Convert String to an array of bytes 
static string message = "ICH"; 

static void Main(string[] args) 
{ 
    SendReceive(); 
} 

static byte[] sendPacket = Encoding.ASCII.GetBytes(message); 

//Create an instance of UdpClient 
static UdpClient client = new UdpClient(); 

static void SendReceive() 
{ 
    try 
    { 
     //Send the string to the specified Server and Port 
     client.Send(sendPacket, sendPacket.Length, server, servPort); 

     Console.WriteLine("Sent {0} bytes to the server...", sendPacket.Length); 

     IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, 0); 

     //Attempt Message reply receive 
     byte[] rcvPacket = client.Receive(ref remoteIPEndPoint); 

     Console.WriteLine("Received {0} bytes from {1}: {2}", 
          rcvPacket.Length, remoteIPEndPoint, 
          Encoding.ASCII.GetString(rcvPacket, 0, rcvPacket.Length)); 
    } 
    catch (SocketException se) 
    { 
     Console.WriteLine(se.ErrorCode + ": " + se.Message); 
    } 

    //Console.ReadKey(); 

    //client.Close(); 
    Thread.Sleep(500); 

    //Endless Loop 
    SendReceive(); 
} 

UDP SERVER:

enter image description here

+1

これは、コードがcmdに表示されているものを実行しているためです。それは各クライアントの応答のバイトを受信し続けるでしょう。したがって、リスト内のアイテムの数が増えるにつれて、サーバーは何度も* Handling client ... *メッセージをエコーし​​ます。あなたの質問は、これとは別にあなたが望むものは不明ですか? –

+0

私の悪い英語を申し訳ありません。 iPアドレスを持つ配列は、クライアントからのすべてのメッセージとともに増加しますが、クライアントが送信した最後のメッセージだけを必要とします。 – Kaputtnix

答えて

0

はiPなアドレスは持つ配列がからのすべてのメッセージと共に成長210クライアント、しかし私は、クライアントが送信した最後のメッセージだけを必要とします。

これが必要な場合は、ループは必要ありません。 arraylistの助けがなければ、remoteIPEndPoint自体を使って個々のクライアントの詳細を表示することもできます。それはあなたが望むことをやるための優しい方法です。

UDPサーバーから次の行を削除します。

... 
     //Send the received Message back to all Clients in the ArrayList 
     for (int i = 0; i < IPArray.Count; i++) 
     { 
      Console.WriteLine("Handling client at " + IPArray[i] + " - " + returnData + " arraylist.Length " + IPArray.Count + "\n"); 

      Byte[] sendBytes = Encoding.ASCII.GetBytes("Clients Send " + returnData + "\n"); 
      client.Send(sendBytes, sendBytes.Length, (IPEndPoint)IPArray[i]); 
     } 
... 

をあなたはIPアドレスとメッセージを送信したクライアントのポート番号を表示する必要があります。代わりに、以下の行を追加します。それは何

//1. Now, you can show the count, but, you can get the indiviudal client detail 
//using the remoteIPEndPoint, there is no need of iterating through the array. 
Console.WriteLine("This message was sent from " + remoteIPEndPoint.Address.ToString() + 
          " on their port number " + 
          remoteIPEndPoint.Port.ToString() + " - " + returnData + "\n"); 

//2. Then send the data back to the individual client without using ArrayList, 
// by passing the client's IPEndPoint in the Send() method. 
Byte[] sendBytes = Encoding.ASCII.GetBytes("Clients Send " + returnData + "\n"); 
client.Send(sendBytes, sendBytes.Length, remoteIPEndPoint); 

することは、IPアドレスやサーバーにメッセージを送信したクライアントのポート番号を示すことである\


また、。現在の方法はネットワーク/ソケットプログラミングのためのより良い方法ではありません。各クライアントのメッセージを受信するには、常にConnectionQueueを使用して個別のスレッドを使用してプール内で制限する必要があります。 ConnectionQueueを使用してスレッドの順序を維持します(新しいクライアント要求ごとに再利用できます)。

関連する問題