2012-02-07 17 views
1

私はCとLinuxでTCPソケットサーバーを実装しています。同時に多くのリクエストを処理するチャットサーバになります。ここでは、それは私が見たものからセットアップC/Linux TCPソケットサーバー

create a socket 
bind to a well-known port 
use listen to place in passive mode 
while (1) 
{ 
    accept a client connection 
    fork 
    if (child) 
    { 
     communicate with new socket 
     close new socket 
     exit 
    } 
else 
{close new socket} 
} 

ある方法についての擬似コードは、「新しいソケットとの通信」の部分はバッファを読んで、その後、おそらくバッファへの書き込みで構成され、その後、ソケットを閉じます。私はソケットが永続的な接続であると考えていたと思いましたか?クライアントがサーバにもっと多くのデータを送信したいときに毎回再接続する必要がある場合、これは非効率的ではなく、ソケットの目的を破るものではありませんか?

+1

あなたの宿題ですか? –

+1

libeventやlibevなどのイベントライブラリを使用する必要があります。 –

+0

すべてのクライアントに 'fork'する必要はありません。 'select'や' poll'(あるいは 'libev'や' libevent'など何かのイベントループを持つライブラリ)のような多重化システムコールの周りにイベントループが必要でしょう。そのライブラリは多重化を行います。 –

答えて

2
  1. ソケットを閉じないでください。メッセージを受信して​​応答するコードをループ内に置き、ブロッキングI/O(デフォルト)を使用して要求が到着するまでソケットの読み取りをブロックします。このようにして、各クライアントを処理し、最小限のリソースを使用するフォークされたプロセスを作成します。完了したため、クライアントが明示的に接続を閉じるときにのみ、ソケットを閉じて子プロセスを終了します。

  2. TCPの代わりにUDPを使用します。この方法では、サーバーとクライアントの間に「接続」はありません。複数のクライアントを1つのソケットに多重化するには、forkしないでください。信頼性を気にしている場合は、各メッセージにシーケンス番号を追加して、それらのメッセージを真っ直ぐに保ち、失敗した場合に再送信できるようにする必要があります。

  3. TCPを使用して1つのプロセスを維持しますが、ソケットディスクリプタセットを保存し、可読ソケットを確認するにはselectを使用してください。その後、そのデータを他のクライアントソケットのそれぞれまたは一部で再送信することができます。

私は、チャットサーバー内の各クライアントの子供をフォークすることは実装が貧弱だと指摘しました。チャットをしたい2人はどうやってコミュニケーションを取るのですか?それぞれのプロセスは個別のプロセスによって処理されます。プロセス間でチャットデータをクライアント間でやりとりするには、どうやって相互に通信しますか?

+0

"信頼性を気にしている場合は、各メッセージにシーケンス番号を追加して、メッセージを真っ直ぐに保ち、失敗した場合に再送信できるようにする必要があります。"< - これはTCPと呼ばれています... – m0skit0

+0

2.信頼性が必要な場合は、*非常に*良い理由がある場合を除き、UDPの使用について考えることさえしないでください(いくつかのユースケースがありますが、それはかなり高度なレベル) –

+0

UDPは、マルチプレイヤーゲームを共有するクライアントを管理しているサーバーなど、多くの速度と実際の識別情報が必要な場合に使用されます。TCPを使用すると、パケットフローが遅くなり、反応速度が遅くなります。ブロードキャスト情報のため – Eregrith

3

さらに多くのデータをサーバーに送信する必要があるたびにクライアントを再接続する必要がある場合、これは効率的ではなく、ソケットの目的を破るものではありませんか?

それはあなたのアプリケーションの性質についての詳細を知らなくても言うことは不可能です:いくつかのケースでは

  • 、それはクライアントの存続期間の期間中、持続的な接続を維持するために理にかなっています。

  • 他のケースでは、すべてのメッセージで接続するとうまくいくでしょう。

効率面ではかなり正しいです.TCP接続の確立にはかなりのオーバーヘッドがあります。したがって、メッセージが頻繁に発生する場合、メッセージごとに新しい接続を設定するのは非常にコストがかかることがあります。

関連する問題