
ひとつ疑問なのですが、たとえばudpでパケットを送信するときに、sockaddr構造体を使って
dest_addr.sin_port = htons(10001);
などで送信先を定義しますよね。このとき、自分の発信元ポートは
決められないのでしょうか。
通信相手がマイコンでして、要求パケットを受けたら自分のステータスを
発信元にそのまま送り返すというシロモノで・・・発信元ポートがわからないと
サーバ側でlistenできないんです・・・。
パケットを拾ったところ、1045発10001着のようにランダムで決められているんですね。
なにかいいアイデアはありますでしょうか?
No.4ベストアンサー
- 回答日時:
少し時間が取れたので、私も試してみました。
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;
この回答への補足
わざわざありがとうございます。
自分の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なのでポートが同じなのは問題ありません)
自分で解釈しながらカスタマイズしてしまったのですが・・・試行錯誤してもわかりませんでした。お手数をおかけしてすみません。
なんとか解決しました。
どうも、ポートがだぶっていてbind()で失敗していたようです。エラー処理をつけたらあっさりと原因がわかりました(^^;
ありがとうございました。
No.3
- 回答日時:
発信元で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台)
ありがとうございます、なんとか解決しました。
bindできないと叫んでいたのは、どうもポートがだぶっていてaddress already in useで失敗していたようです。エラー処理をつけたら簡単に見つかりました(おバカです・・・)
どうもありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 格安スマホ・SIMフリースマホ 日本通信Simで通信量を使い切り、低速制限を受けていますが、この間にパケット使用量は発生しますか? 4 2023/07/07 16:18
- メルカリ らくらくメルカリ便 スマホを送った 箱が3 cm 以上ありました ゆうパケットではだめ? 1 2023/02/08 23:32
- 格安スマホ・SIMフリースマホ 【楽天モバイル】楽天モバイルはパケット通信料が減らない低速モードに切り替えられる公式 3 2022/12/21 07:48
- docomo(ドコモ) ドコモの114サービスで、パケット通信中となるのは 電話の時以外もありますか? 先日主人の携帯を調べ 2 2022/12/08 11:28
- UNIX・Linux Ubuntuサーバーでメールを受信できない 7 2022/08/23 20:55
- 固定IP スマホやPCのIPアドレスについて教えてください。 5 2023/07/07 19:53
- メルカリ 「メルカリ」相手からのコンビニ払いがされたか不明の状態でゆうパケットポストで発送してしまいました。 1 2023/01/17 21:13
- Wi-Fi・無線LAN PCWi-Fiの設定方法がわからなくて困っています。 4 2022/12/28 18:30
- Gmail SPFレコードとDNSサーバーについて、gmailを設定できるかどうか 2 2023/06/10 23:55
- 格安スマホ・SIMフリースマホ おすすめのesimを教えてください 2 2023/07/18 15:39
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
wsdlからのサービス化を行い。
-
UDPを使って帯域測定プログラム...
-
UDP通信する時に、相手にどうや...
-
USB通信について
-
SIPがNATを越えられない理由
-
クライアントサーバ型アプリ製...
-
ソケットにおけるメッセージの...
-
Javaの通信系クラスを利用した...
-
Visual BASIC Express 2015 を...
-
エクセル VBA でのCOMポート...
-
C#で簡単なサービスアプリを書...
-
ソケットを用いた1対多通信につ...
-
Javaのソケット通信について初...
-
ソケット通信 同じポート番号...
-
read()メソッドを使ったループ...
-
Macターミナルで実行中のプログ...
-
CPad for LSI C-86の実行結果
-
秋月PICプログラマーを使っ...
-
グラフィックLCD SG12...
-
PIC16F84Aから16F628Aの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信におけるbind関数について
-
Winsockで接続待ちタイムアウト...
-
UDP通信する時に、相手にどうや...
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットでクライアントのipア...
-
ソケットを用いた1対多通信につ...
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
UdpClient 送信元のIPアドレ...
-
相手のIPアドレスを取得する方法
-
recv関数でフリーズしてしまう
-
closeされたsocketへの動作につ...
-
送信したデータの一部が文字化...
-
UDP通信(SNMP)したいが、うま...
-
ソケット通信
-
Connectエラーが出てしまう・・...
-
WinSockでの通信プログラムがう...
おすすめ情報