サンプルで覚えるNetwork Programing Echoクライアント

   2017/07/09

以前、Echoサーバ(その1)を作った続きで、クライアントを作成してみました。 前回と同様に動作させた環境は、以下となります。

  • CentOS6.8 x86_64

 

クライアントプログラムの主な流れは次の様になります。

  • ソケットの作成 socket()を呼び出してソケットディスクリプタを取得、以降ではこのディスクリプタによりソケット経由で通信する。
  • バインド 明示的に使用するIPを指定したい場合はバインドする。ここではバインドしていない。
  • コネクト クライアントからコネクト関数を呼び成功すると送受信が可能となる。
  • 送受信 recv(), send()で送受信できる。

ソケットの作成とコネクトするclient_socket関数、送受信をするsend_receive関数は以下の通り。

 

 

クライアント側も、まずsocket関数を呼びソケットを作ります。サーバと同様で第一引数のAF_INETは、IPv4インターネットのソケットであることを指定している。 それ以外のApple Talkや、IPXを指定することもできますが、通常のプログラムではまずAF_INET以外はないと思います。 第二引数は、通信方式を指定します。TCPプロトコルで通信する場合は、SOCK_STREAM、UDPの場合は、 SOCK_DGRAMです。特別なプログラムをしない限り、この2つを知っていればOKです。 第三引数は、プロトコルを指定しますが、与えられた一つのプロトコルのみの機能で良ければ通常0にします。 するとOSが適切なプロトコルを選択します。

ソケットが作成できたら、バインドすることもできますが、サーバのIPとポート番号を指定してconnect関数を呼びます。 connectが成功すれば、サーバとの送受信が可能な状態になります。

データの送受信をするコードを次に示します。

 

ここで作成したsend_receive関数では、select 関数を使って入力の多重化を行っています。 recv関数は、ディスクリプタがブロッキングモードの場合、入力があるまで処理をそこで待ち続けてしまいます。 ディスクリプタをノンブロッキングにしてしまうと入力が無い場合は、forループをCPUの速度全開で回ってしまいますので効率が悪いです。 待ち時間を入れることである程度改善することはできますが。。。 select関数へ渡す第一引数は、設定した最大のディスクリプタ値 + 1となります。 第二引数は、読み込み用ディスクリプタがセットされたfd_setというデータタイプを渡します。 第三引数は、書き込み用なのでここでは、NULLに設定しています。 第四引数は、例外監視用ですのでこれも、NULLに設定しています。 最後の第五引数は、タイムアウトの時間をマイクロ秒単位で設定できます。 select関数の返値は、-1がエラーで、0の場合は何も起こらずタイムアウトを表します。 それ以外の場合は、何らかの準備ができているディスクリプタが存在するということなので、どのディスクリプタが準備できているか調べていくことになります。

select関数に渡すfd_set型の値は、まずFD_ZEROというマクロでゼロクリアし、FD_SETマクロで設定していきます。 また、select関数は、渡したfd_set型の値を書き換えてしまいますので、ループの初めで毎回元の値に書き直すということをしています。

上のサンプルでは、ソケットのディスクリプタの準備ができていればrecv関数でbufに読み込みを行い、その文字列を標準出力に表示しています。標準入力の準備ができている場合は、文字列をsend関数でサーバ側に送信します。

あとは、main関数を作成し、クライアントとして動作させます。

 

クライアントをサーバに繋いでみた実行サンプル。

サーバをポート2000で起動。

$ sudo ./server 2000
accept client IP:192.168.1.2 Port:48160
Received from client: hoge
Received from client: hogehoge
recveive EOF

 

クライアントでサーバに接続し、何か文字をタイプする。

$ ./client 192.168.1.1 2000
hoge
Received from server: hoge:OK
hogehoge
Received from server: hogehoge:OK
ここでCtl-Cをタイプ

 

今回のクライアントサンプルは、ここからダウンロードできます。

 

  • このエントリーをはてなブックマークに追加
  • Pocket

この記事へのコメントはこちら