2

xクライアントをリッスンするTCPサーバーを設計したいと思います。Xは小さく、たとえば10前後で固定されています。クライアントはいつでも接続できます。接続が確立されたら(accept()成功すると)、クライアントごとにスレッドを生成して処理します。

このhandle()関数では、クライアントにコマンドを送信し、それに応じてデータを受信します。

問題: サーバーからコマンドが送信されると、クライアントはデータを継続的に送信して応答します。クライアントにコマンドを返送して停止するにはどうすればよいですか?現在のコードと同様に、私はクライアントからデータを受信するループに入っています。

  1. 受信の進行中にサーバースレッドからコマンドを送信する方法がわかりません。たとえば、接続が確立されたら別のスレッド(コマンドを送信するため)が必要ですか?
  2. クライアントから継続的にデータを受信し、同時にコマンドを送信するにはどうすればよいですか?ユーザー入力に基づいて各クライアントにコマンドを送信します。(ユーザーがclient1にデータの送信を開始させたい場合は、STARTをclient1に送信する必要があります。ユーザーはclient1の送信を停止したいので、STOPをclient1に送信する必要があります。ユーザーがdata3cmdをクライアント4に送信したい場合はコマンドDATA3をclient4などに送信します。この場合、クライアントをどのように識別しますか?基本的に小さなプロトコルを形成します**

以下のコードは、ソケットでリッスンでき、クライアントが接続してデータを送信できる場所で機能しています。ユーザーが入力したコマンドを適切なクライアント(たとえばclient4)に送信し、同時に受信する方法がわかりません。

4

4 に答える 4

1

データを本当に継続的にストリーミングし、並行してコマンドを交換したい場合は、コマンドチャネルを確立するための追加の接続を回避することはできません。代替案は、ある種の多重化です。データのチャンクをストリーミングし、コマンドをチェックし、次のチャンクをストリーミングし、コマンドを再度チェックします...-ストリームが継続的に中断されるため、複雑でエラーが発生しやすくなります...

石の古いftpプロトコルは似たようなことをします:http://en.wikipedia.org/wiki/Ftphttps://www.rfc-editor.org/rfc/rfc959(2.3章のアスキーアートを参照)

于 2013-02-25T17:50:30.533 に答える
0

私は過去に、同時に通信できない低レベルのデバイス用に独自の双方向プロトコルを設計することを楽しんでいました。使用できる方法の1つは、相互譲歩です。クライアントとサーバーとの間でメッセージをやり取りするためのメカニズムを確立します。送信する必要のあるコマンドまたはメッセージをストリーミングしてから、ストリームを反対側に渡します。次に、反対側がメッセージまたはコマンドをストリーミングし、ストリームを元の側に渡します。このメカニズムの唯一の問題は、国際インターネット接続などの高ping接続では非常に遅延することです。

これはすでに言及されていますが、私はそれを再ハッシュしたほうがよいでしょう。コンピュータにはすでにネットワークハードウェアに多重化が組み込まれているため、「同時」の送信/受信呼び出しを行うことができます。接続ごとにスレッドのペアを実行するだけです。recvスレッドとsendスレッドです。これは最も堅牢なソリューションであるはずです。

于 2013-02-25T19:42:54.497 に答える
0

WOO HOO!あなたはかなり毛むくじゃらの主題に飛び込むことに決めました、私の友人。

最初にあなたの問題を言い換えさせてください:あなたのプログラムは一度に一つのことしか待つことができません。待っている場合はreceive、待つことはできませんsend。したがって、送信と受信を同時に行うことはできません。

これは多重化によって解決されます:複数のものを待つこと。

  1. グーグルキーワード:io、、、、multiplexingselectpoll
  2. SO関連の質問:selectを使用して同じソケット(TCP)に対して読み取りと書き込みを行う

別のアプローチは、nonblocking-read -> nonblocking-write -> sleepループに入ることです。これは明らかに最適とは言えませんが、あなたの場合には十分かもしれません。

于 2013-02-25T17:45:30.297 に答える
0

別のスレッドにコマンド送信要求を開始させたい場合は、標準の非同期I / Oを使用して、別のチャネル(パイプ)を追加して他のスレッドからコマンドを受信することで、目的を達成できます。擬似コード:

Master thread:
while(1) {
    newsocket = accept(listen socket)
    pipefds = pipe()
    new thread(Receiver, newsocket, pipefds.read)
}

Receiver thread:
while(1) {
    readfds = [ pipefds.read, newsocket ]
    poll( readfds )  // wait for there to be data on one of the fds
    if (data ready on newsocket) {
           read (newsocket)
           process data
    }
    if (data ready on pipefds.read) {
           read (pipefds.read)
           send command
    }
}

Commander thread:
write (pipefds.write, command)

メインのReceiverループのselectは、ソケットで読み取るデータがあるとき、または別のスレッドがリモート接続に送信する必要のあるコマンドを送信した場合にウェイクアップします。

情報を検索するための主要なシステムコールはpoll(またはselect)、およびpipeです。

于 2013-02-26T17:18:46.747 に答える