こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

延々と受信し続けるwinsockのrecv

以下のサーバープログラムを用いて、
(acceptしたらスレッド作成し、作成が終ったということをクライアントに知らせるために文字列送信後受信待機している)
#include <winsock2.h>
#include <vector>
#include <process.h>
#include <algorithm>

char *Ver = "0.00";
using namespace std;
unsigned __stdcall Patch( void *Sock );

int main()
{
----WSADATA wsaData;
--------WSAStartup( MAKEWORD(2,0), &wsaData );

----SOCKET RecvSock = socket( AF_INET, SOCK_STREAM, 0 );
----SOCKET SendSockBuf;
----vector<SOCKET> SendSock;

----fd_set ConnectFds, SubConnectFds;

----struct sockaddr_in Recv, Send;

----int len = sizeof(Send);

----Recv.sin_family = AF_INET;
----Recv.sin_port = htons(55555);
----Recv.sin_addr.S_un.S_addr = INADDR_ANY;
--------bind(RecvSock, (struct sockaddr *)&Recv, sizeof(Recv) );

----FD_ZERO( &SubConnectFds );
--------FD_SET( RecvSock, &SubConnectFds );

----listen( RecvSock, 5 );

----vector<unsigned int> thID;
----vector<HANDLE> hTh;
----struct timeval tv;
--------tv.tv_sec = 0;
--------tv.tv_usec = 0;
----while(1)
----{
--------memcpy( &ConnectFds, &SubConnectFds, sizeof(fd_set) );
--------select( 0, &ConnectFds, NULL, NULL, &tv );
--------if ( FD_ISSET(RecvSock, &ConnectFds) )
--------{
------------SendSockBuf = accept(RecvSock, (struct sockaddr *)&Send, &len);
------------if( SendSockBuf != INVALID_SOCKET)
------------{
----------------SendSock.push_back( SendSockBuf );
----------------thID.push_back( hTh.size() );
----------------hTh.push_back( (HANDLE)_beginthreadex(NULL, 0, Patch, &SendSock[hTh.size()], 0, &thID[hTh.size()]) );
------------}
--------}
----}
----closesocket(RecvSock);

----WSACleanup();
----return 0;
}

unsigned __stdcall Patch( void *Sock )
{
----SOCKET *SendSock = (SOCKET *)Sock;
----send( *SendSock, Ver, 5, 0 );

----char Str[5];
----while( Flag == 0 )
----{
--------recv( *SendSock, Str, 5, 0 );
----}
----closesocket( *SendSock );

----return 0;
}

以下のようなクライアントプログラムで文字を送信すると、
#include <WinSock2.h>

using namespace std;

void main()
{
----WSADATA wsaData;
--------WSAStartup( MAKEWORD(2,0), &wsaData );
----SOCKET Sock = socket( AF_INET, SOCK_STREAM, 0 );

----struct sockaddr_in Addr;
--------Addr.sin_family = AF_INET;
--------Addr.sin_port = htons(55555);
--------Addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

----connect( Sock, (struct sockaddr *)&Addr, sizeof(Addr) );
----char str[5];
----recv( Sock, str, 5, 0 );
----send( Sock, "0.00", 5, 0);
----shutdown( Sock, 2 );
----closesocket( Sock );
}
クライアントプログラムは終了しているのにサーバープログラムは"0.00"を受信し続けます。

どこがおかしいのか分からないので教えてください

投稿日時 - 2013-06-12 20:39:53

QNo.8131195

すぐに回答ほしいです

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

> while( Flag == 0 )
> {
>  recv( *SendSock, Str, 5, 0 );
> }

このループはいつ終了するんでしょう?
ループ中にFlagは変化しませんから最適化で無限ループになっていたりしませんか?

recv()の戻り値は捨てていますが、クライアントが切断したらrecv()が0を返却していたりしませんか?
# その際『Str[]の内容は変化しない』のを受信し続けていると認識していませんか?

recv()で5バイト受信できない。ということも可能性としてはあり得ますがその辺りはどう考えていますか?
# 2バイト、3バイトと受信する可能性がある。
# まぁ実際にはないでしょうけど。

投稿日時 - 2013-06-12 21:00:53

お礼

バグが起こるプログラムでバグに関係ないと思われる箇所を削っていったため、一生終らないループになってしまいました。

>その際『Str[]の内容は変化しない』のを受信し続けていると認識していませんか?
恥ずかしながらその通りでした。戻り値の事をすっかり忘れていました。

5バイト受信できない可能性に関してもwhileでの理由と同様に関係なさそうなので削除しました。(実際には5バイトではない)

ありがとうございます。
凄い基本的なことを見落としていました。

投稿日時 - 2013-06-12 21:24:58

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問