• ベストアンサー

recv関数でフリーズしてしまう

現在Winsockを用いた簡単なパケット送受信のソフトを作成しています。 開発環境はVisual Studio2008で、ダイアログベースで作成しています。 パケットの受信側の処理なんですが、いつパケットが来てもいいように、 Ontimerで、定期的に受信処理をしようと思っています。 そこでOntimer内に以下のようにプログラムしたところ、コンパイルエラー はないものの、数秒経つと応答なしとなりフリーズしてしまいます。 原因を探ったところrecv関数が原因で、recv関数をコメントアウトした ところ、フリーズはしなくなりました。また、エラー処理は省略していま すが、ソケットの作成失敗などはありませんでした。 なぜrecv関数でフリーズが起きてしまうのか、原因が分かる方は いらっしゃいますか? OnTimer(UINT nIDEvent){ WSAData wsaData; SOCKET sock; struct sockaddr_in addr; char buf[2048]; 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)); memset(buf, 0, sizeof(buf)); recv(sock, buf, sizeof(buf), 0); closesocket(sock); WSACleanup(); }

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

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.4

いつパケットがきてもいいようにという目的で、 OnTimerを使うのは、そもそも発想が違うというか。 確実にタイマ指定時間毎にOnTimerが呼ばれる保証はないんじゃなかったっけか。 受信専用のスレッドを立てて、その中で、 select, recvを使うのが一般的じゃないかな。 recvはブロッキング関数なので、データが受信されない限り 抜けてくることはない。つまりスレッドが1つのアプリならば、フリーズする。 まあ、それを避けるためにselectを使って、データが到着しているか 調査するんだけどね。 データが到着していれば、recvを呼んでもデータが受信されて、関数を抜けてくるので。

その他の回答 (3)

  • reset_cat
  • ベストアンサー率68% (94/138)
回答No.3

select()ではなく、WSAAsyncSelect()かWSAEventSelect()を使ってみてはどうでしょう? もしど~してもselect()でやるのならば、ioctlsocket()をsoclet()の後で呼び出す手もありますが・・・

  • reset_cat
  • ベストアンサー率68% (94/138)
回答No.2

select()またはWSAEventSelect()を使用していないので、作成したダイアグラムソケットがブロッキングモードで動作しているからではないですか? listen()はストリームソケットで使うもので、今回は該当しないでしょう。 他にもWSAStartup()とWSACleanup()をOnTimerに入れてるなど変なところもありますが・・・

fondrive2
質問者

補足

早速の回答ありがとうございます。 select関数は試していたのですが、select関数でも同様に フリーズが起きてしまっています。 デバッグしてみても、select関数の文で動作がとまってしまいます。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.1

普通 listen(), select() しませんか?

関連するQ&A