現在、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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Excel(エクセル) excelvbaのenableeventsについて 3 2022/08/30 11:20
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- その他(プログラミング・Web制作) google formsを使ったタスク依頼フォーム作成におけるご相談 1 2023/06/22 15:55
- UNIX・Linux raspberry piを使ったWebサーバー制作をしています、接続するネットワークを変更したときに 1 2023/01/09 15:57
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- その他(パソコン・周辺機器) Windowsマシン。USBタップの「自動切れ、再接続」がうざい。解決策は? 7 2023/01/25 08:27
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
このQ&Aを見た人はこんなQ&Aも見ています
-
性格の違いは生まれた順番で決まる?長男長女・中間子・末っ子・一人っ子の性格の傾向
同じ環境で生まれ育っても、生まれ順で性格は違うものなのだろうか。家庭教育研究家の田宮由美さんに教えてもらった。
-
Winsockで接続待ちタイムアウトを設定する方法
C言語・C++・C#
-
socket: recvはいつ,どれだけ受け取るのか?
C言語・C++・C#
-
非同期関数とノンブロッキング関数について(winsock)
C言語・C++・C#
-
-
4
recv関数でフリーズしてしまう
C言語・C++・C#
-
5
WaitForSingleObjectの使い方について
C言語・C++・C#
-
6
winsock windowprocでFD_WRITEの処理
C言語・C++・C#
-
7
<unistd.h>をVisualStudioでつかえるようにする
C言語・C++・C#
-
8
ネットワーク切断を検出するには?
C言語・C++・C#
-
9
Winsockでの送受信についての質問
C言語・C++・C#
-
10
エディットボックスの入力制限について
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
UDP通信におけるbind関数について
-
WinSockでの通信プログラムがう...
-
C#とTCP/IPを利用したサーバー...
-
ソケット通信 同じポート番号...
-
winsockでファイル転送
-
Winsockで接続待ちタイムアウト...
-
Socket通信の0バイト受信について
-
POP3S
-
どうか、POSTでのファイル転送...
-
UDP通信する時に、相手にどうや...
-
fsockopenのソケットが全然分か...
-
SIPがNATを越えられない理由
-
Linuxのsocket接続でacceptでき...
-
空きポートの取得方法
-
Winsockプログラムの初歩的質問...
-
エクセル VBA でのCOMポート...
-
VB6のwinsockでconnectできない
-
ソケットを用いた1対多通信につ...
-
相手のIPアドレスを取得する方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
TCP/IP通信時のサーバーからの受信
-
recv関数でフリーズしてしまう
-
Winsockで接続待ちタイムアウト...
-
UDP通信におけるbind関数について
-
エクセル VBA でのCOMポート...
-
Socket通信の0バイト受信について
-
VB6のwinsockでconnectできない
-
ソケットのrecvの戻り値が0
-
ソケットを用いた1対多通信につ...
-
UdpClient 送信元のIPアドレ...
-
ソケットでクライアントのipア...
-
UDP通信する時に、相手にどうや...
-
ソケット通信 同じポート番号...
-
同じLAN内パソコンのIPアドレス...
-
Connectエラーが出てしまう・・...
-
ソケットのクローズについて
-
CreateFile関数でCOMポートが開...
-
異なる言語間でのソケット通信...
-
C言語でHTTP1.1のキープアライ...
-
送信したデータの一部が文字化...
おすすめ情報