################################################################################ ●send,sendto,read,write,recv ################################################################################ 1.send,sendto int send(int s, char *msg, int len, int flags) int sendto(int s,char *msg, int len, int flags, struct sockaddr *to, int tolen) データの送信を行なう。 あらかじめconnect等によって通信相手が明らかなソケットに 使う。 sendtoは引数toで指定される通信相手に対して送信を行なう。 flagsには、オプ ションが使える。 戻り値は実際に送信されたデータのバイト数。 戻り値がlenより小さい場合がある。これを予測してプログラミングして下さい。 送信するデータは一度システムのバッファに蓄えられます。このバッファにはサイズに 限界があり、満杯になると lenより小さい値が戻ってきます。 もし、システムのバッファがすでに満杯だった場合には、少しでも空きができるまで、 send()内でブロックされます。 システムのバッファに空きがあるかどうか調べる方法は、select()を使用します。 送信がネットワークのエラーなどで失敗した場合は-1が返ってきます。 UNIX系OSでは、-1が与えられる前にシグナルSIGPIPEが発生します。 2.read int read(int fd, char *buf, int nbyte) ファイルディスクリプタfd に対する読み込みを行なう。 ファイルディスクリプタはファイルをどこまで読んだかを保持しており、その位置から nbyteバイトの内容をbufに入れる。返り値は読み込んだバイト数。 3.write int write(int fd, char *buf, int nbyte) ファイルディスクリプタfd に対する書き込みを行なう。 bufの内容をファイルに書き込むことを除けばreadと同様。 3.recv int recv(int fd, void *buf, int nbyte, uint flags) ソケットからデータを受信する。ソケットディスクリプタfdからの読み込みを行なう。 3.flags ・MSG_PEEP:受信後、受信バッファをクリアしない ・MSG_OOB:ストリーム外部から受信する ・MSG_WAITALL:指定したバイト数まで読み込む(ブロックに使える!) 4.send/writeの違い メッセージ送信に使用する場合は結果的に相違は有りません。 writeがファイル(ファイルデスクリプタ)に対する書込みと言う点で、 ソケットも扱 えると言えます。(ソケットもファイルとして扱う)逆にsendはファイルデスクリプタ への書込みは出来ません。 あまり違わないと言われているが、でも実は大きな違いがあります! send()には第4パラメタがあり、ソケットに対する制御(非ブロッキングやストリーム 外部への送信)が可能です。 5.read/writeの戻り値とエラーコードからの断検出 5.1 受信 read @リタン値: 読み込んだバイト数:正常 0:コネクション断(と判断して良いです) -1:エラーコード参照 Aエラーコード EINTR:システムコールが割込まれました。(コネクション断と判断して良いです) EAGAIN:これ以上プロセスは作成できません。 EISDIR:これはディレクトリです。 EBADF:ストリームが不正です。 EINVAL:引数が無効です。 EFAULT:アドレスに問題があります。 5.2 送信 write @リタン値: 書き込んだバイト数:正常 書き込もうとしたバイト数より小さい:ファイルサイズの制限かバッファ不足 -1:エラーコード参照 Aエラーコード EINTR:システムコールが割込まれました。(コネクション断と判断して良いです) EAGAIN:これ以上プロセスは作成できません。 EISDIR:これはディレクトリです。 EBADF:ストリームが不正です。 EINVAL:引数が無効です。 EFAULT:アドレスに問題があります。 EPIPE:パイプが壊れています。 ENOSPC:ディスクに空き領域がありません。 5.3 その他 ソケットが切れた時にシグナルが発行されるので、プロセスでシグナルを受ける処 理を持っておく事で断を検出できます。相手から断なのか、自分から断なのか等の 判断が出来るかは調査していません。(出来ないでしょう) ################################################################################ 実装 ################################################################################ メッセージキュー通信、TCP/UDP通信でsend,recv,write,readを使用し確実な通信を行う 為の方法を示す。 @送受信の無間待ち ・アプリケーションのトラフィックを削減するために、無限待ちを行いたい。即リタン で受信をしたかどうかを判断し受信するまでループさせるようなプログラムはオーバー ヘッドが大きい。 ATCP/UDPから全データを確実に受信する ・受信するサイズを先に判断し(先にヘッダ部のレングスを参照する)、受信サイズが期 待サイズになるまで、受信を繰り返す。 Bブロッキイング回避の為にselectを上手く使用する。 Cインターバルタイマの為にselectを上手く使用する。