2016-05-16 2 views
1

私はネットワーキングをプログラミングする方法を学んでいます。私はudpclientクラスの代わりにソケットを使用してudpシステムを作成しようとしています(検索を通して多くの情報が見つかりませんでした)。UDP受信またはsendtoが動作しない

サーバはクライアントからメッセージを受信して​​印刷しますが、クライアントはスレッドをブロックした受信先に固執します。 ここで何が間違っていますか?

私のサーバーコード:

Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 

IPEndPoint _IPEndPoint = new IPEndPoint(IPAddress.Any, 55566); 
EndPoint _EndPoint = _IPEndPoint; 
sck.Bind(_IPEndPoint); 

byte[] buffer = new byte[ 255 ]; 
int rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref _EndPoint); 
Array.Resize(ref buffer, rec); 
string clientIP = Encoding.Default.GetString(buffer); 
Console.WriteLine("Received: {0}", clientIP); 

buffer = new byte[ 255 ]; 
rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref _EndPoint); 
Array.Resize(ref buffer, rec); 
int clientPort = BitConverter.ToInt32(buffer, 0); 
Console.WriteLine("Received: {0}", clientPort); 

buffer = Encoding.Default.GetBytes("Hello " + clientIP); 
sck.SendTo(buffer, 0, buffer.Length, SocketFlags.None, new IPEndPoint(IPAddress.Parse(clientIP), clientPort)); // never gets received 

sck.Close(); 


Process.GetCurrentProcess().WaitForExit(); 

とクライアントコード:

Socket sck = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 55566); 
sck.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 0)); 
EndPoint endPoint = ipEndPoint; 

string msg = new Func<string>(() => 
{ 
    var host = Dns.GetHostEntry(Dns.GetHostName()); 
    foreach (var ip in host.AddressList) 
    { 
     if (ip.AddressFamily == AddressFamily.InterNetwork) 
     { 
      return ip.ToString(); 
     } 
    } 
    throw new Exception("Local IP Address Not Found!"); 
})(); 
byte[] msgBuffer = Encoding.Default.GetBytes(msg); 
Console.WriteLine("sending IP"); 
sck.SendTo(msgBuffer, 0, msgBuffer.Length, SocketFlags.None, ipEndPoint); 

msgBuffer = BitConverter.GetBytes(((IPEndPoint) sck.LocalEndPoint).Port); 
Console.WriteLine("sending port"); 
sck.SendTo(msgBuffer, 0, msgBuffer.Length, SocketFlags.None, ipEndPoint); 

byte[] buffer = new byte[ 255 ]; 
Console.WriteLine("receiving message"); 
int rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint); // gets stuck here 

Array.Resize(ref buffer, rec); 

Console.WriteLine("Received: " + Encoding.Default.GetString(buffer)); 

sck.Close(); 

答えて

0

それはあなたがテストしているしている環境についての詳細を知らなくても、確かに言うことは不可能です。しかし、クライアントが間違ったIPアドレスやポートを送信している可能性があります。

サーバは、クライアントのアドレスを報告するためにクライアント自身に頼るべきではありません。サーバーはReceiveFrom()メソッドからの情報を知り、の情報のみを使用してデータを送り返す必要があります。例えば

:もちろん

EndPoint clientEndPoint = new IPEndPoint(IPAddress.Any, 0); 

rec = sck.ReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref clientEndPoint); 
Array.Resize(ref buffer, rec); 
int clientPort = BitConverter.ToInt32(buffer, 0); 
Console.WriteLine("Received: {0}", clientPort); 

buffer = Encoding.Default.GetBytes("Hello " + clientIP); 
sck.SendTo(buffer, 0, buffer.Length, SocketFlags.None, clientEndPoint); // never gets received 

、UDPは信頼できないことに注意してください。 UDPを使用する場合、以下のすべてが該当します。

  1. データグラムが到着しないことがあります。
  2. 任意のデータグラムが複数回受信される可能性があります。
  3. 送信されたデータグラムは、送信された順序に関係なく、任意の順序で到着する可能性があります。

当然のことながら、これらの特性は、コードは、データがいくつかの特定の順序で、任意の並べ替えや重複せずに送信され、受信されると仮定し、あなたが書かれたもののようなコードで大混乱をもたらすことができます。

関連する問題