プロが教える店舗&オフィスのセキュリティ対策術

送信側
#include <winsock2.h>
#include <string.h>
int
main()
{
WSAData wsaData;

SOCKET sock;
struct sockaddr_in addr;
int len;
typedef struct recv {
char Name[32];
int Flag;
} RECV;

RECV send;

WSAStartup(MAKEWORD(2,0), &wsaData);

sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

strcat(send.Name, "ABC");
send.Flag=12;
len=sizeof(send);
sendto(sock,(char *)&send,len, 0, (struct sockaddr *)&addr, sizeof(addr));

closesocket(sock);

WSACleanup();

system("pause");

return 0;
}

受信側


#include <stdio.h>
#include <winsock2.h>
#include <string.h>

int
main()
{
typedef struct rcv {
char Name[32];
int Flag;
} RECV;
WSAData wsaData;

SOCKET sock;
struct sockaddr_in addr;

int len;

RECV rcv;

WSAStartup(MAKEWORD(2,0), &wsaData);

sock = socket(AF_INET, SOCK_DGRAM, 0);

addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.S_un.S_addr = INADDR_ANY;

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

len=sizeof(rcv);
recv(sock,(char *)&rcv, len, 0);

printf("%s [%d]\n",rcv.Name,rcv.Flag);

closesocket(sock);

WSACleanup();

system("pause");

return 0;
}

winsockを使ったUDP通信プログラムで構造体データを送る事が出来ないのですが
どこに誤りがあるのでしょうか?
コンパイルは通ってるのですが、送信側を起動しても受信側で受け取ることが出来ていない状況です。

A 回答 (5件)

>ちゃんと初期化しなかったのが原因であってますか?



原因の一つではありますが、それが全てではありません。
大本の原因は不適切な関数の使用でしょう。

>strcat(send.Name, "ABC");

strcat()ではなくstrcpy()を使うべきではありませんか?

上から順にコードを読んだ人は、ここでstrcat()を使用することに違和感を覚えるでしょう。

連結ってことはここより前になにか文字列を設定しているハズ。
ということはコードの見落としがあったのか?確かめないと。
見落としはなかった、文字列の設定もされていないのになんで連結なんだろう?
define定義で関数コールが隠蔽されていたのかも知れない。そっちも確認しないと。

などなど。
    • good
    • 0

>送信側のバグと言うのは 単純なミスでしょうか?


>それとも 知識不足でミスを犯しているのでしょうか?

・ただのタイプミス
・元々使うつもりだった関数と似てる関数名のものを間違って使用した
・関数の仕様を微妙に勘違いしていた

など色々考えられます(上記にはヒントっぽいもの入ってます)。
    • good
    • 0

>addr.sin_family = AF_INET;では確かに2が代入されていたので。


>sendto 内がおかしいのがわかりました。

sendto()がおかしいのではなく、sendto()が期待する値が入っていないのがおかしい…んですけどね。

addr.sin_family = AF_INET;
から
sendto()までの間をステップ実行(あるいはprintf()でaddr.sin_familyの値を表示)していけば、
どこで壊されたのか?
というのは特定可能なハズです。

スパっと答えを書いてもいいのでしょうけど、それだといつまで経っても自分でデバッグする技術が身に付きませんしね。

>送信側のバグと言うのは 単純なミスでしょうか?
>それとも 知識不足でミスを犯しているのでしょうか?

まぁ、単純なミスが重なっただけ…でしょう。
未初期化のローカル変数の値がどうなっているのか?
とか、使用する関数は適切か?という。

この回答への補足

memsetで構造体内のchar型の変数を0で埋めてみると
うまくいきました。
ちゃんと初期化しなかったのが原因であってますか?

補足日時:2014/01/17 22:27
    • good
    • 0

http://www.geekpage.jp/programming/winsock/udp.php
で「エラー処理は省いてあります。 実際にコードを書く場合にはエラー処理も行ったコードにして下さい。 」と書かれていますよね?

で、エラー処理しましたか?

>sendto(sock,(char *)&send,len, 0, (struct sockaddr *)&addr, sizeof(addr));
が正常終了を返しましたか?
私の手元では-1が返却され、GetLastError()してみたらWSAEAFNOSUPPORTが返されました。
「指定したファミリのアドレスはこのソケットでは使用できません。」
となります。

addr.sin_family = AF_INET;
で設定しているにも関わらずそんなエラーが出るのはおかしい!!
ということで、sendto()でブレークして値を確認してみます。
ws2def.hで
#define AF_INET 2
となっているので2が設定されているハズですが、全然違う値が設定されています。

ということは、どこかで破壊するコードが紛れ込んでいる事になります。
では、どれが????

って感じでデバッグして下さい。
# まさに指摘されている送信側のバグだったりしますけどね。

この回答への補足

AF_INETに定義されている2ではなく16642という値が
sendtoのaddr.sin_familyに入っていました。

addr.sin_family = AF_INET;では確かに2が代入されていたので。
sendto 内がおかしいのがわかりました。

送信側のバグと言うのは 単純なミスでしょうか?
それとも 知識不足でミスを犯しているのでしょうか?

補足日時:2014/01/15 01:21
    • good
    • 0

「送信側を起動しても受信側で受け取ることが出来ていない状況」とは, 具体的にはどう「できていない」んですか?



# とりあえず送信側のバグには目をつむることとして.
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!