
現在、Winsock2を使ってあるサーバーのプログラムを作成しています。
WSAEventSelect関数を使って非ブロッキングソケットを扱っているのですが、複数のクライアントからほぼ同時に接続要求などがあった際に
接続を取りこぼしてしまいます。
どなたかアドバイスいただけませんでしょうか。
以下、ソースを示します。プログラムの動作をわかりやすくするためエラー処理などは省略して記載します。(実際には行っています)
ちなみに非ブロッキングソケットを使用する理由は以下のとおりです。
・GUIアプリのワーカースレッドで動作させており、ブロッキングソケットでブロック中にメインスレッドが終了してもワーカースレッドがそれを知る術がなくワーカースレッドを安全に終了させることができないため。
/* 変数の宣言*/
intiRet=-1;
SOCKETListenSock;
SOCKETAcceptSock;
intiRcvClientLen=0;
intiRcvLen=0;
charcaRcvDat[1024]={0};
WSAEVENThEvent;
DWORDdwResult;
WSANETWORKEVENTSevents;
/* リッスンソケットを作成*/
ListenSock = socket(AF_INET, SOCK_STREAM, 0);
/* イベントのクリエイト*/
hEvent = WSACreateEvent();
/* リッスンソケットの設定*/
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT_NUM);/*PORT_NUMは定数*/
addr.sin_addr.S_un.S_addr = INADDR_ANY;
/* リッスンソケットをバインド*/
iRet = bind(ListenSock, (struct sockaddr *)&addr, sizeof(addr));
/* リッスンソケットでポートを開く*/
iRet = listen(ListenSock, 10);
/* クライアント接続待ちの無限ループ*/
while (1) {
printf("\n\n/--------- 待機中---------/\n\n");
iRcvClientLen = sizeof(client);
/* リッスンソケットにACCEPTイベントを設定*/
iRet = WSAEventSelect(ListenSock, hEvent, FD_ACCEPT);
/* ACCEPTイベント発生まで待機*/
dwResult = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE);
/* 発生したイベントを解析*/
iRet = WSAEnumNetworkEvents(ListenSock, hEvent, &events);
/* イベント変数をリセット*/
WSAResetEvent(hEvent);
/* 発生したイベントがACCEPTであれば接続を受け入れる*/
if(events.lNetworkEvents & FD_ACCEPT){
AcceptSock = accept(ListenSock, (struct sockaddr *)&client, &iRcvClientLen);
}
/* ACCEPTしたソケットにREADイベントを設定しなおす*/
iRet = WSAEventSelect(AcceptSock, hEvent, FD_READ);
/* READイベント発生まで待機*/
dwResult = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE);
/* 発生したイベントを解析*/
iRet = WSAEnumNetworkEvents(AcceptSock, hEvent, &events);
/* イベント変数をリセット*/
WSAResetEvent(hEvent);
/* 発生したイベントがREADであればデータを読み込む*/
if(events.lNetworkEvents & FD_READ){
iRcvLen=recv(AcceptSock, caRcvDat, 1024, 0);
/* ・・・以下Recv後の動作・・・*/
}
}
おそらく、2回目のWSAWaitForMultipleEvents関数で待機している間に接続要求が来たクライアントを取りこぼしているのだと思いますが、
対処方法がわかりません。
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
WSAEventSelect()使ったことありませんが…
# というかサーバ側プログラム書いたことないですが。
疑問点として…
WSAResetEvent()をsocket関連の関数をコールする前に実施して問題ないのか?
とか…
>/* ACCEPTしたソケットにREADイベントを設定しなおす*/
>iRet = WSAEventSelect(AcceptSock, hEvent, FD_READ);
イベントを「使い回す」のではなく、ListenSock用とAcceptSock用で別々に持ったらどうなのか?
とか…
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
Winsockで接続待ちタイムアウトを設定する方法
C言語・C++・C#
-
ネットワーク切断を検出するには?
C言語・C++・C#
-
ソケット通信で接続クライアントの上限を設ける
C言語・C++・C#
-
-
4
エディットボックスで改行
その他(プログラミング・Web制作)
-
5
CStringをwchar_tに変換したい
C言語・C++・C#
-
6
非同期のプロセス間通信(パイプ)で全データ受信する
C言語・C++・C#
-
7
ソケット通信で同時受信の制限?
C言語・C++・C#
-
8
socket: recvはいつ,どれだけ受け取るのか?
C言語・C++・C#
-
9
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
10
winsockでソケット通信の開発をしていますが、
C言語・C++・C#
-
11
エディットボックスの入力制限について
C言語・C++・C#
-
12
エディットコントロールでEnter押した時の動作
C言語・C++・C#
-
13
CString から LPCTSTRの型に変換
C言語・C++・C#
-
14
スレッドの終了の仕方
C言語・C++・C#
-
15
ソケットのクローズについて
C言語・C++・C#
-
16
SocketのSend関数でのCLOSEの検知 [Linux]
C言語・C++・C#
-
17
SetDlgItemTextの使い方について
C言語・C++・C#
-
18
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
19
charからLPTSTRへの変換方法
C言語・C++・C#
-
20
非同期関数とノンブロッキング関数について(winsock)
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Winsockで接続待ちタイムアウト...
-
ソケットのrecvの戻り値が0
-
ftpクライアントでの接続後の、...
-
recv関数でフリーズしてしまう
-
UDP通信におけるbind関数について
-
Socket通信での通信異常について
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
closeされたsocketへの動作につ...
-
ネットワークプログラミングに...
-
C言語でチャットプログラミング...
-
Javascritpでソケット通信?
-
C言語でHTTP1.1のキープアライ...
-
ソケットプログラミングに関す...
-
TCP/IP通信時のサーバーからの受信
-
Socketの使用方法について
-
fsockopenのソケットが全然分か...
-
ソケット通信の送受信遅延-02 ...
-
C#とTCP/IPを利用したサーバー...
-
空きポートの取得方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信する時に、相手にどうや...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
ソケットのクローズについて
-
ソケットのrecvの戻り値が0
-
VB6のwinsockでconnectできない
-
Socket通信の0バイト受信について
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
Connectエラーが出てしまう・・...
-
送信したデータの一部が文字化...
-
【ajax】 XMLHttpRequestオブジ...
-
ソケット通信
-
closeされたsocketへの動作につ...
-
wsdlからのサービス化を行い。
-
Cにおける通信プログラミングの...
-
UdpClient 送信元のIPアドレ...
-
非ブロッキングソケットのrecv...
-
ソケットを用いた1対多通信につ...
おすすめ情報