ページ 1 / 1
C++ TCPの受信ループにつきまして
Posted: 2018年4月14日(土) 22:40
by tonton
こんにちは。
とてもサイトが様変わりして驚いております。
(スレッド作成時の質問が難しい…)
コード:
std::map<int,int> clinetSockList;
// Clientの受け入れ待ちスレッド
int clinetSock = accept(serverSock, (struct sockaddr *)&client, &len);
clientSockList[count] = clientSock;
// 受信ループスレッド
iterator it = clientSockList.begin();
// 受け入れたClientの数だけRecvを呼んで、データが無いかをチェックする
while(it != clientSockList.end())
{
//ノンブロック設定済み
recv(*it);
++it
}
私は現在上記の様なコードでTCPの受信ループ処理を書いております。
この方法ではClientの数が1万人や10万人となった時に毎回その人数分ループが走り、非常に宜しくない事となります。
どうにかして必要最小限のRecvを呼びたいと考えておりますが、もし他に良い書き方が御座いましたらご教授頂けますと幸いです。
(出来ればパケットを受信しているSocketを的確に知りたい…)
もし上記のやり方が普通だよ、という事でしたら自信が持てるというか安心致します。
宜しくお願い致します。
Re: C++ TCPの受信ループにつきまして
Posted: 2018年4月15日(日) 10:01
by にこよん
すみません回答ではないです
私もwinsock2で通信しようとしているのですが、localhostでしか通信に成功しておらず、他PCからのIP検索では全く通信できていないです(クライアントからのconnect関数で失敗する)
質問に対してこのようなスレッドで申し訳ないのですが、差支えなければクラスなどのその通信ソースを見せていただけないでしょうか?m(__)m
Re: C++ TCPの受信ループにつきまして
Posted: 2018年4月15日(日) 10:38
by YuO
tonton さんが書きました: ↑7年前
私は現在上記の様なコードでTCPの受信ループ処理を書いております。
この方法ではClientの数が1万人や10万人となった時に毎回その人数分ループが走り、非常に宜しくない事となります。
どうにかして必要最小限のRecvを呼びたいと考えておりますが、もし他に良い書き方が御座いましたらご教授頂けますと幸いです。
map<int, int>ということはunix系を利用している前提で良いでしょか。
オフトピック
WindowsだとソケットはSOCKET型を使うので
recv(std::pair<int,int>)の内容がよくわかりませんが,unix系だとselectを利用した非ブロッキングI/Oが基本かと。
ディスクリプタの配列を用意しておいて,selectして,FD_ISSETでイベントを確認する形です。
https://www.ibm.com/support/knowledgece ... nblock.htm
なお,10万のTCP接続を1つのIPアドレスで同時に処理することはできません (ポートが16bit分しかないため)。
10万の接続を受け入れたいのであれば,複数台で処理したり,TCPの接続時間を短くするなどの別の工夫が必要になります。
Re: C++ TCPの受信ループにつきまして
Posted: 2018年4月15日(日) 13:43
by tonton
>>にこよん様
パブリック(グローバル)IPで送受信出来ないという事であれば、にこよん様の記載された処理というよりはどちらかのPCのファイアーウォールあるいはルーターの設定が怪しいかと思われます。
問題の切り分けとして
①自分のPC、レンタルサーバーの送受信をテストしてみる
②レンタルサーバーを2台借りて、同じソースコードでレンタルサーバー同士の送受信を試してみる
(②で動作すればソースコードに問題は御座いません。
私もほとんどサンプルコードで御座いますし技術的にも稚拙で御座いますので、ここにいらっしゃる他の方々にお尋ね頂いた方が宜しいかと思われます。
>>Yuo様
ServerがLinux、ClientはWinで行っております。
Selectの仕様を勘違いしておりました。狙った挙動が実装出来そうです。
>なお,10万のTCP接続を1つのIPアドレスで同時に処理することはできません (ポートが16bit分しかないため)。
すっかり失念してしまっておりました。
ログイン等を管理するMasterServerを一台置いて、ゲーム処理を行うGameServerを増やしていき負荷分散を行う予定でしたが、考えを改める必要がありますね…。
RUDPを導入してみるなど少し根本から設計を見直してみます。
ご回答有難う御座いました。
Re: C++ TCPの受信ループにつきまして
Posted: 2018年4月15日(日) 14:21
by にこよん
このような質問にご回答いただきありがとうございます
確認方法のご教授ありがとうございましたm(__)m
参考にやってみようと思います
Re: C++ TCPの受信ループにつきまして
Posted: 2018年4月16日(月) 20:57
by tonton
>>Yuo様
ちょっと本日色々と眺めておりまして
http://d.hatena.ne.jp/ryousanngata/20091122/1258838710
こちらに記載されてます通り、selectを用いた場合であっても
コード:
// 各ソケットの状況チェック
for(i=0; i<FD_SETSIZE; i++){
if(accept_list[i] != -1 && FD_ISSET(accept_list[i], &fds)){
の様にFD_ISSETで全Socketをループさせて確認しなければならないという認識で正しいでしょうか?
そうなるとノンブロックのrecvを全ループさせるのと結局の所流れとしては同じなのでしょうかね。
処理負荷、処理時間の計測はしておりませんので、そうした面で有利という可能性はありますね。
宜しくお願い致します。