- PR -

C# UDP通信について

1
投稿者投稿内容
KenTarO
常連さん
会議室デビュー日: 2007/02/10
投稿数: 42
投稿日時: 2007-03-13 15:50
Aプログラム⇒Bプログラムに「UDP送信」をした際に、Aプログラムは正常にデータを送信しているのですが、Bプログラムが受信できません。
下記のメソット(myUdpServer)の「udp.Receive(ref remoteEP);」でリプライが帰ってきません。
当現象に詳しい方がいらっしゃいましたら、ご掲示お願いいたします。
  ★C#初心者なので、なかなか理解できずに困っております★


/// <summary>
/// UDPサーバー送受信メソッド
/// </summary>
/// <param name="port"></param>
public void myUdpClient(Int32 port)
{
try
{
Encoding enc = Encoding.UTF8;

UdpClient udp = new UdpClient(port);

hostinfo.data = Console.ReadLine();
byte[] sendBytes = enc.GetBytes(hostinfo.data);
udp.Send(sendBytes, sendBytes.Length, hostinfo.hostip, port);

IPEndPoint remoteEP = null;
byte[] rcvBytes = udp.Receive(ref remoteEP);
string rcvMsg = enc.GetString(rcvBytes);
Console.WriteLine("送信したデータ:{0}", rcvMsg);
//Console.WriteLine("送信元アドレス:{0}/ポート番号:{1}",
// remoteEP.Address, remoteEP.Port);

udp.Close();

Console.ReadLine();

}
catch
{
hostinfo.errmsg = "[Error] : UdpClient error";
}
}

/// <summary>
/// UDPサーバー送受信メソッド
/// </summary>
/// <param name="port"></param>
public void myUdpServer(Int32 port)
{
try
{
Encoding enc = Encoding.UTF8;


IPEndPoint remoteEP = null;
byte[] rcvBytes = udp.Receive(ref remoteEP);
string rcvMsg = enc.GetString(rcvBytes);
Console.WriteLine("受信したデータ:{0}", rcvMsg);
Console.WriteLine("送信元アドレス:{0}/ポート番号:{1}",
remoteEP.Address, remoteEP.Port);

udp.Close();

Console.ReadLine();

}
catch
{
hostinfo.errmsg = "[Error] : UdpClient error";
}
}


}
未記入
大ベテラン
会議室デビュー日: 2006/12/15
投稿数: 157
投稿日時: 2007-03-14 09:49
初心者とのことですので、プログラムの不具合なのか環境の問題なのかを切り分けるために、
動きそうなサンプル(DOBON.NET > プログラミング道 > .NET Tips > インターネット)で試して、原因の切り分けを行ってみて下さい。

掲載されたソースはオリジナルですか?それともどこかのサンプルですか?
KenTarO
常連さん
会議室デビュー日: 2007/02/10
投稿数: 42
投稿日時: 2007-03-14 13:56
未記入さん、ありがとうございます。
掲載したソースは、WEBのサンプルを元に作った(途中の物ですが・・)ものです。

【プログラムイメージ】
UDP送信プログラム(UdpClientクラスのSend())
↓ ↓ ↓ ↓
(UDP通信)
↓ ↓ ↓ ↓
UDP受信プログラム(UdpClientクラスのReceive())

【質問】
UDP送信プログラムは正常に送信出来ているように見えるのですが、UDP受信プログラムがReceive()で処理が戻らなくなります。
UDP受信プログラムを待機(Receive()で待たせる)させている状態で、UDP送信プログラムがデータを送信すれば、UDP受信プログラムが受信して先の処理に入る(Receive()から戻ってくる)という認識でよいのでしょうか?

 #いまいちReceive()のパラメータの意味とか、使用方法がわからない状態です。#
未記入
大ベテラン
会議室デビュー日: 2006/12/15
投稿数: 157
投稿日時: 2007-03-14 15:54
過去ログ

参考色々

後はがんばれ。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2007-03-14 22:23
引用:

UDP受信プログラムを待機(Receive()で待たせる)させている状態で、UDP送信プログラムがデータを送信すれば、UDP受信プログラムが受信して先の処理に入る(Receive()から戻ってくる)という認識でよいのでしょうか?


合っています。

引用:

UDP送信プログラム(UdpClientクラスのSend())
↓ ↓ ↓ ↓
(UDP通信)
↓ ↓ ↓ ↓
UDP受信プログラム(UdpClientクラスのReceive())



myUdpClientのRecive()が帰ってこないのか、myUdpServerのRecive()が帰ってこないのか
どちらですか?
KenTarO
常連さん
会議室デビュー日: 2007/02/10
投稿数: 42
投稿日時: 2007-03-15 08:46
>> myUdpClientのRecive()が帰ってこないのか、myUdpServerのRecive()が
>> 帰ってこないのかどちらですか?

myUdpServerのReceive()が帰ってこない状況に陥ります。

クライアント側ではメッセージ送信後に、正常に終了しています。
サーバ側のReceive()でメッセージ受信待ちしている状態で、クライアント側から
メッセージを送信しても、サーバ側で受信せずにメッセージ受信待ちの状態に陥って
しまいます。


下記が現在作成しているUDP送受信テストプログラムです。
-------------------------------------------------
【クライアントプログラム】
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class UDPMulticastSender
{

private static IPAddress GroupAddress =
IPAddress.Parse("192.168.1.1");
private static int GroupPort = 11000;

private static void Send(String message)
{

Console.WriteLine("in Send() message = {0}", message);
UdpClient sender = new UdpClient(GroupPort);
IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);
Console.WriteLine("groupEP = {0}", groupEP);

try
{
Console.WriteLine("Sending datagram : {0}", message);
byte[] bytes = Encoding.ASCII.GetBytes(message);

sender.Send(bytes, bytes.Length, groupEP);

sender.Close();

}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

}

public static int Main(String[] args)
{
string cmd;

cmd = Console.ReadLine();
Console.WriteLine("cmd = {0}", cmd);
Send(cmd);

return 0;
}
}

-----------------------------------------
【サーバプログラム】
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class UDPMulticastListener
{

private static readonly IPAddress GroupAddress =
IPAddress.Parse("192.168.1.1");
private const int GroupPort = 11000;

private static void StartListener()
{
Console.ReadLine();

bool done = false;

UdpClient listener = new UdpClient(GroupPort);
IPEndPoint groupEP = new IPEndPoint(GroupAddress, GroupPort);
try
{
Console.WriteLine("listener before");
Console.WriteLine("GroupAddress = {0}, GroupPort = {1}", GroupAddress, GroupPort);
Console.ReadLine();
listener.JoinMulticastGroup(GroupAddress);
Console.WriteLine("connect before");
Console.ReadLine();
listener.Connect(groupEP);

while (!done)
{
Console.WriteLine("Waiting for broadcast");
byte[] bytes = listener.Receive(ref groupEP);

Console.WriteLine("Received broadcast from {0} :\n {1}\n",
groupEP.ToString(),
Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
Console.ReadLine();
listener.Close();

}
catch (Exception e)
{
Console.ReadLine();
Console.WriteLine(e.ToString());
}

}

public static int Main(String[] args)
{
StartListener();

return 0;
}
}
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-03-15 11:25
何点かデバッグの方法を指摘しておきます。

1)まず送信の問題なのか、受信の問題なのか切り分けてください。Send()から正常に戻ってきても、物理的に送信できているのか否かは分かりません。フリーのネットワークモニターツールを使えば意図したパケットがネットワークに創出されているか否か、すぐに判断がつきます。

2)ネットワークの環境設定を良く確認してください。最近は標準でFirewallが有効になっていることも多く、設定を変更する必要があるかもしれません。

4)netstatコマンドを用いて、意図したポートがちゃんとイニシャルされているか確認してください。netstatで表示されないなら、初期化手順を間違えている証拠です。

5)コードを乗せるときにはBBコードを使ってください。インデントの滅茶苦茶なコードを読み解く気には到底なれません。なかなか回答をもらえない原因にもなります。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2007-03-15 23:21
マルチキャストの話だったのですか?
であれば、最初からそれを説明しておいて下さい。
送信側の手順はマルチキャストでもユニキャストでも同じですが、受信側は異なります。

(1)
グループアドレスがユニキャストになっています。これではダメです。
ちゃんとマルチキャストアドレスにしましょう。

(2)
受信側のUdpClientをグループアドレスにconnectしてはダメです。
送信者を限定したいなら、送信元アドレスを指定してconnectしましょう。
普通は、connectしません。(誰からの送信でも受け取る)

MSDNのサンプルコードにグループアドレスにconnectする例が出ていますが、
あれはマチガイです。

(3)
単純なアンマネージド・スイッチで接続された同一LAN内なら問題ありませんが、
それ以上複雑なネットワーク構成でマルチキャストを通したいなら、
ネットワーク機器の設定に注意が必要です。

[ メッセージ編集済み 編集者: coasm 編集日時 2007-03-15 23:31 ]
1

スキルアップ/キャリアアップ(JOB@IT)