0

これは私の場合です。接続をリッスンするサーバーと、現在プログラミング中のクライアントがあります。クライアントはサーバーから何も受信しませんが、3 分ごとにステータスの更新を送信する必要があります。

私は現時点で以下を持っています:

    WSAStartup(0x101,&ws);
    sock = socket(AF_INET,SOCK_STREAM,0);
    sa.sin_family = AF_INET;
    sa.sin_port = htons(PORT_NET);
    sa.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    connect(sock,(SOCKADDR*)&sa,sizeof(sa));
    send(sock,(const char*)buffer,128,NULL);

私のアプローチはどうあるべきですか?recv のループを回避できますか?

4

1 に答える 1

0

それはあなたが望む振る舞いとあなたのプログラム構造にかなり依存しています。デフォルトでは、ソケットは読み取りまたは書き込み操作をブロックします。つまり、サーバーのメインスレッドに接続をポーリングさせようとすると、3分間、またはクライアントがクライアントを閉じるまで、ソケットが「フリーズ」することになります。繋がり。

絶対的に最も単純な機能ソリューション(マルチスレッドなし)は、ソケットを非ブロッキングに設定し、メインスレッドでポーリングすることです。しかし、それは避けたいようです。

それを回避する最も明白な方法は、すべての接続に専用のスレッドとメインリスナーソケットを作成することです。サーバーは着信接続をリッスンし、作成するストリームソケットごとにスレッドを生成します。次に、各接続スレッドは、データを受信するまでソケットをブロックし、それ自体を処理するか、共有キューにシャントします。これは、かさばる複雑なソリューションです。開閉が必要な複数のスレッド、保護が必要な共有リソースです。

もう1つのオプションは、ソケットを非ブロッキングに設定することです(win32ではsetsockoptを使用するため、タイムアウトを設定し、* nixではO_NONBLOCKフラグを渡します)。そうすれば、読み取ることができるデータがない場合に制御を返します。ただし、これは、妥当な間隔でソケットをポーリングする必要があることを意味します(「合理的」は完全に自分次第であり、サーバーが新しいデータを処理するために必要な速度)。

個人的には、あなたが説明している軽量の使用のために、上記の組み合わせを使用します:数秒ごとにソケット(または非ブロッキングソケットの配列)をポーリングし、その間にスリープし、単にデータをプッシュする単一の専用スレッドメインスレッドがメインループ中に動作するためのキュー。

非同期プログラムを混乱させる方法はたくさんあるので、制御フローに慣れるまでは、単純にして機能させるのがおそらく最善です。

于 2012-04-13T14:46:49.670 に答える