アプリ版:「スタンプのみでお礼する」機能のリリースについて

お世話になります。

VC6.0でソケット通信の社内の既存のプログラムを改善しております。

クライアントより、サーバにソケットで大量に電文を送信した時に、サーバ側の処理が重くなってしまいます。
NETSTATコマンドで確認したところ、
サーバ側では、CLOSE_WAITが大量に出力されており
クライアント側では、FIN_WAIT_2が大量に出力されます。
クライアント側のFIN_WAIT_2は、時間が経つと消えるのですが、サーバ側のCLOSE_WAITは残ってしまっております。
サーバ側のEXEを再起動すると、CLOSE_WAITは消えます。

サーバ側のソケットの受信後の処理に問題があるのではと考えておりますが、何処が問題なのかわからない状態です。

コードを以下に記述致します。

WINAPI K010cListener{
/*Winsock初期化*/
WSAStartup(wVersionRequested,&wsaData);
/*SOCKET作成*/
fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)

/*ポートの設定*/
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_family = AF_INET;
addr.sin_port = htons(usPortNo);
addrlen = sizeof(addr);
/*BIND*/
bind(fd,(struct sockaddr*)&addr,addrlen)

/*LISTEN*/
listen(fd,0)

while(1){
/*ACCEPT*/
fd2 = accept(fd,(struct sockaddr*)&addr,&addrlen)

//データ受信
waitReceiveThread(fd2, &rcv_msg);

//DBオープン
ConnectDB()
//DB登録
AddTable(&rcv_msg)
//DBクローズ
CloseDB()
}

/*Winsock終了*/
WSACleanup();
}

void waitReceiveThread(SOCKET fd, SockRcvMsg *rcv_msg) {

while (1) {
/*データ受信待ち*/
rcvSize = recv(fd,rcvBuf,sizeof(rcvBuf),0);
if (rcvSize <= 0) {
continue;
}
else {
/* 返信電文の準備 */
memset(sndBuf,0x20,sizeof(sndBuf));
memcpy(sndBuf ,"RCMORDER00004800000000",22);

/* 返信電文の送信 */
send(fd,(char*)sndBuf,sizeof(sndBuf),0);

/* バッファの初期化 */
bufsize=0;
memset(buf,'\0',sizeof(buf));

break;/*ループを抜ける*/


}
}
}

恐れ入りますが、ご教授いただければ幸いです。
宜しくお願い申し上げます。

A 回答 (1件)

waitReceiveThread()においてrecv()の戻り値rcvSizeが0以下の場合、そのコネクションは切断された物として処理するのが妥当だと思います。

origin_93様の書かれたプログラムでは無理やりcontinueしてrecv()を繰り返しいるため、切断後の正常動作は期待出来ません。

かなり大雑把ですが、一般的なサーバの動作は下記の流れの様になります。

 while (TRUE) {
  socket();
  bind();
  listen();

  while (TRUE) {
   accept();

   while (TRUE) {
    ret = recv();
    if (ret <= 0) break;
    else {
     受信処理
    }
   }
  }
 }

一番外側のループは要らないかもしれませんが、socket()等の戻り値がエラーだった場合を考慮しています。
複数のクライアントが接続するならば、acceptの後で受信スレッドを生成し、そのままループします。acceptで取得したレシーブソケットは受信処理のループを抜けた所でクローズして構いません。
    • good
    • 0
この回答へのお礼

上記コードに、内側のループをbreakし、acceptする前にclose処理を入れてで作成したところ、問題なく動作しました。

誠にありがとうございました。

お礼日時:2010/02/03 20:12

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