OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

Linuxでパケットを発信する際・・・。

  • すぐに回答を!
  • 質問No.101707
  • 閲覧数2030
  • ありがとう数2
  • 気になる数0
  • 回答数4
  • コメント数0

お礼率 88% (361/410)

ひとつ疑問なのですが、たとえばudpでパケットを送信するときに、sockaddr構造体を使って

dest_addr.sin_port = htons(10001);

などで送信先を定義しますよね。このとき、自分の発信元ポートは
決められないのでしょうか。

通信相手がマイコンでして、要求パケットを受けたら自分のステータスを
発信元にそのまま送り返すというシロモノで・・・発信元ポートがわからないと
サーバ側でlistenできないんです・・・。

パケットを拾ったところ、1045発10001着のようにランダムで決められているんですね。
なにかいいアイデアはありますでしょうか?
通報する
  • 回答数4
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.4
レベル14

ベストアンサー率 50% (1122/2211)

少し時間が取れたので、私も試してみました。

a-kuma> ポート番号だけじゃなくて、相手先のIPアドレスもきちんと設定しましたよね?

何を言ってるんでしょうね。思い付きの方は良かったのに、頭の中が腐ってる
ようです (^^;

No.3 の Fooky さんも「さっきやった間違い」とあるので、私だけが特に そこつ者
なわけではないようですが、思い込みがあったので、ちょっとはまりました。

■送信側

int sock = socket(PF_INET, SOCK_DGRAM, 0);

sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(2500);  // このポートに返して欲しい
addr.sin_addr.s_addr = INADDR_ANY;
bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in));

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(1999);  // 送信の為のポート
memcpy(&addr.sin_addr.s_addr, gethostbyname("相手のホスト名")->h_addr_list[0], sizeof(addr.sin_addr.s_addr));

char* buf = "test message";
sendto(sock, buf, strlen(buf) + 1, 0, (sockaddr*)&addr, sizeof(sockaddr_in));


■受信側

int sock = socket(PF_INET, SOCK_DGRAM, 0);

sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(1999);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(sock, (sockaddr*)&addr, sizeof(sockaddr_in));

char buf[256];
int len;
recvfrom(sock, buf, sizeof(buf), 0, (sockaddr*)&addr, &len);
cout << "port: " << htons(addr.sin_port) << endl;
補足コメント
pythian

お礼率 88% (361/410)

わざわざありがとうございます。
自分のsockaddrをbindして、相手のaddrでsendtoするということですね。
ということは、ソケット転送のプログラムなので、

////////////////////////////////////
udp_socket = socket(AF_INET, SOCK_DGRAM,0);

memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_addr.sin_port = htons(10001);
bind(udp_socket, (struct sockaddr *) &my_addr, sizeof(my_addr));
// クライアントからポート10001でデータを受信する
////////////////////////////////////

////////////////////////////////////
udp_socket2 = socket(AF_INET,SOCK_DGRAM,0);

bind(udp_socket2, (struct sockaddr*)&my_addr, sizeof(my_addr));

memset(&dest_addr, 0, sizeof(dest_addr));
dest_addr.sin_family = AF_INET;
dest_addr.sin_addr.s_addr = inet_addr("192.168.253.1") ;
dest_addr.sin_port = htons(10001);
// 192.168.253.1のポート10001へデータを送信する
////////////////////////////////////

という形でいいのでしょうか?(長くてすみません・・・)
実は、これで試したところ再度1051番辺りからパケットが出てしまいまして・・・。
(ダブルNICなのでポートが同じなのは問題ありません)

自分で解釈しながらカスタマイズしてしまったのですが・・・試行錯誤してもわかりませんでした。お手数をおかけしてすみません。
投稿日時 - 2001-07-11 13:59:47
お礼コメント
pythian

お礼率 88% (361/410)

なんとか解決しました。
どうも、ポートがだぶっていてbind()で失敗していたようです。エラー処理をつけたらあっさりと原因がわかりました(^^;
ありがとうございました。
投稿日時 - 2001-07-13 14:08:29
-PR-
-PR-

その他の回答 (全3件)

  • 回答No.1
レベル14

ベストアンサー率 50% (1122/2211)

> このとき、自分の発信元ポートは決められないのでしょうか。 普通 UDP で送信 sendto() するときには、bind() はしなくても良いのですが、 bind() してから、sendto() してみてはどうでしょうか? # ちょっと思い付いただけで、試してみてません ...続きを読む
> このとき、自分の発信元ポートは決められないのでしょうか。

普通 UDP で送信 sendto() するときには、bind() はしなくても良いのですが、
bind() してから、sendto() してみてはどうでしょうか?

# ちょっと思い付いただけで、試してみてません
補足コメント
pythian

お礼率 88% (361/410)

パケットのモニタリングをしながらやってみたのですが、bindしてみたところ、sendtoしても全くパケットが出なくなってしまいました・・・。難しいですね...(^_^;
投稿日時 - 2001-07-09 15:57:02


  • 回答No.2
レベル14

ベストアンサー率 50% (1122/2211)

> bindしてみたところ、sendtoしても全くパケットが出なくなってしまいました ポート番号だけじゃなくて、相手先のIPアドレスもきちんと設定しましたよね? # 思い付きで振り回すのも、アレなんですが… (^^; ...続きを読む
> bindしてみたところ、sendtoしても全くパケットが出なくなってしまいました

ポート番号だけじゃなくて、相手先のIPアドレスもきちんと設定しましたよね?

# 思い付きで振り回すのも、アレなんですが… (^^;
補足コメント
pythian

お礼率 88% (361/410)

はい。とりあえず、ソケット生成後の
sockaddr.sin_family
sockaddr.sin_port
sockaddr.sin_addr.s_addr
の3つは設定してあります。
思いつきだなんてとんでもない、ありがとうございます(^^;;
投稿日時 - 2001-07-09 17:27:09
  • 回答No.3
レベル9

ベストアンサー率 71% (59/82)

発信元でbind()して出来ませんか? 手元のプログラムをちょっと変えて 実験してみたら問題なくできましたよ。 ・発信元ソケットにbindするポート番号は  1025以上を使っているか? => bind()でPermission denied   1024以下なら、スーパーユーザにならない   とダメ ・他のプロセスが既に使っているポート番号を  使っていないか?=> ...続きを読む
発信元でbind()して出来ませんか?
手元のプログラムをちょっと変えて
実験してみたら問題なくできましたよ。

・発信元ソケットにbindするポート番号は
 1025以上を使っているか? => bind()でPermission denied

  1024以下なら、スーパーユーザにならない
  とダメ

・他のプロセスが既に使っているポート番号を
 使っていないか?=> bind()でAddress already in use

あと、私がさっきやった間違いなんですが、

・bind()に渡すsockaddr構造体の値を代入する際に、
 sendto()に渡すsockaddr構造体への代入を真似て
 書きませんでしたか?=> sendto()でInvalid argument

  bind()に渡す分をsockaddr_in srcadr;とし、  
  sendto()に渡す分をsockaddr_in dstadr;とすると、
  srcadrの方は、sin_addr.s_addrにINADDR_ANYをセットし、
  dstadrのsin_addrメンバには、gethostbyname()で取得した
  hostent構造体のh_addr_list[0]の中身をコピーする。

私がさっき実験したときに気付いたのはこの程度です。
とにかく、方法としてはa-kumaさんが指摘された
方法で行けるようですよ。

(実験環境Linux-2.2.14 × 2台)
お礼コメント
pythian

お礼率 88% (361/410)

ありがとうございます、なんとか解決しました。
bindできないと叫んでいたのは、どうもポートがだぶっていてaddress already in useで失敗していたようです。エラー処理をつけたら簡単に見つかりました(おバカです・・・)
どうもありがとうございました。
投稿日時 - 2001-07-13 14:09:53
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ