@IT会議室は、2009年4月15日に新システムに移行し、さらに2012年5月29日にITエンジニアに特化した
質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用くださいませ。
- PR -

WinSock2ソケットプログラミングについて

投稿者投稿内容
ばーど
常連さん
会議室デビュー日: 2005/08/03
投稿数: 32
投稿日時: 2006-08-29 12:16
こんにちは。IP Networkで質問させていただくのか迷いましたが、こちらで投稿させていただきます。

私は現在、VC++.NETでWinSockを用いたUDPソケットプログラミングを行っています。以下のようなプログラムを作りたいと思っているのですがうまく動作しません。

[概要]
A:送信端末
B:受信端末

1.Aから文字列"send"をB端末へ送信。
2."send"を受信した受信端末Bは、A端末へ文字列"ok"を送信。

この1と2の動作を行わせたいと思っています。この場合、A,B端末は送信と受信を行う必要があります。

[問題点(うまくいかない点)]
A→Bへ"send"は送信でき、B端末で受信できるのですが、B端末からA端末へ送信できません。B端末で送信できているのか、それともA端末で受信できていないのか?が分からない状態です。

[気づいた点]
ポート番号を分ける必要があるのでしょうか?例えば、A→Bへは9000番。B→Aへは9001番という意味です。

送信と受信を行うため、送信・受信で2つのUDPソケットを使用する必要があるのでしょうか?例えば、
s1 = socket(AF_INET, SOCK_DGRAM, 0);←送信に利用
s2 = socket(AF_INET, SOCK_DGRAM, 0);←受信に利用

よろしくお願いします。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-08-29 13:35
引用:

ばーどさんの書き込み (2006-08-29 12:16) より:
[問題点(うまくいかない点)]
A→Bへ"send"は送信でき、B端末で受信できるのですが、B端末からA端末へ送信できません。B端末で送信できているのか、それともA端末で受信できていないのか?が分からない状態です。


挙動がよくわからない時はキャプチャしましょう。
パケットがDROPされている可能性も高いです。
引用:

[気づいた点]
ポート番号を分ける必要があるのでしょうか?例えば、A→Bへは9000番。B→Aへは9001番という意味です。

送信と受信を行うため、送信・受信で2つのUDPソケットを使用する必要があるのでしょうか?


分ける必要ないです。
shutdownかけてりゃ別ですけど。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2006-08-29 15:44
UDP で通信しようとしているのですよね?

であればソケットは送信用と受信用でふたつ作成する必要があります。受信用に使うソケットはローカルアドレスにバインドします。

UDP は非接続型なので TCP のような send, recv はできないと思っていたほうが良いです。UDP では sendto, recvfrom を使用したほうが非接続という意識を持てるのでオススメです。実際には UDP でも connect によって既定の接続先を記憶させておくことで send が使用できるのですが・・・。これはあくまでも接続先を記憶しているような振る舞いであり、TCP のソケット接続動作とはまったく意味合いが異なります。

引用:
A→Bへ"send"は送信でき、B端末で受信できるのですが、B端末からA端末へ送信できません。B端末で送信できているのか、それともA端末で受信できていないのか?が分からない状態です。


UDP であれば B→A の送信は A→B とまったく同様のコーディングでおこなえます。TCP の場合は受信側は accept によってソケットを取得してそこに send することで接続元に情報を返すことができますが、UDP ではそのようなことはできません。A, B どちらも同じ方法(sendto) で送信処理を行い、どちらも同じ方法(recvfrom)で受信を行います。

引用:
ポート番号を分ける必要があるのでしょうか?例えば、A→Bへは9000番。B→Aへは9001番という意味です。


ローカルアドレスにバインドする必要があるのは受信ソケットだけなので、ポートは同じでもかまいません。

それと、WinSock2 の質問ということですが・・・ 実際にはバークレーソケットマクロを使われているようですので、Insider.NET 会議室よりは Master of IP Network 会議室もしくは Linux Square 会議室のほうが回答が付きやすいかもしれません。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-08-29 16:39
引用:

未記入さんの書き込み (2006-08-29 15:44) より:
であればソケットは送信用と受信用でふたつ作成する必要があります。受信用に使うソケットはローカルアドレスにバインドします。



これってどういう意味ですか?

送信側と受信側の各ホストにひとつずつという意味ならば合ってますが。
A:9000 <-> B:9000というソケットの構成で双方向通信できますよ。
ばーど
常連さん
会議室デビュー日: 2005/08/03
投稿数: 32
投稿日時: 2006-08-29 17:06
こんにちは。
多数の書き込みありがとうございます。

自身の質問の仕方が悪かったのかもしれません、再度書き込みします。

[質問内容(再度)]
A(送信端末)⇔B(受信端末)というふうに、AとB端末でUDPソケットを用いて送受信させたいと思っています。

みなさんの書き込み内容を拝見させていただいて・・・
・AとB両端末のポート番号は9000番にする。
・各端末に送受信用にソケットを2つオープンするのか?それとも、AとB端末に各1つオープンする?のどちらでしょうか・・・?

現在作成していますが、やはり・・・A→Bは可能ですが、B→Aはできません。
試行錯誤しながら頑張ってみます。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2006-08-29 17:14
引用:
これってどういう意味ですか?



元の質問に以下のような書き込みがあります。
コード:
s1 = socket(AF_INET, SOCK_DGRAM, 0);←送信に利用 
s2 = socket(AF_INET, SOCK_DGRAM, 0);←受信に利用 


s1 はパケットディスクリプタとして送信時に sendto の引数に指定します。s2 は待ち受け用として bind します。これは、端末A, 端末B ともにおこなう必要があるので、socket 関数は合計で 4 回使用することになります。そういう意味で(端末ごとに)送信用、受信用ふたつ作成する必要がある、と書きました。

引用:
送信側と受信側の各ホストにひとつずつという意味ならば合ってますが。
A:9000 <-> B:9000というソケットの構成で双方向通信できますよ。


アプリケーション全体としてみれば結果として「双方向通信」を実現していることになりますが、ソケット通信という狭い視点で考えた場合、この UDP 関連の文脈で「双方向通信できますよ」を出すのは混乱の元かと思います。
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2006-08-29 17:20
あー、もしかして。自分はやったことないのですが・・・。

ソケットがひとつで済むというのは、受信用に socket -> bind したソケットを、送信時に sendto でも流用できるということですか?
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2006-08-29 18:42
引用:

未記入さんの書き込み (2006-08-29 17:20) より:
あー、もしかして。自分はやったことないのですが・・・。

ソケットがひとつで済むというのは、受信用に socket -> bind したソケットを、送信時に sendto でも流用できるということですか?


流用するというよりは、その方が一般的なのでは?

アイティメディアの提供サービス

ホワイトペーパー(TechTargetジャパン/閲覧には会員登録が必要です)

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