『TCP/IP ソケットプログラミング C言語編』を読む
第1章 ネットワークとプロトコルの概要
1.1 ネットワーク、パケット、プロトコル
第2章 ソケットの基礎
code: TCPEchoClient_1.c
memset(&echoServAddr, 0, sizeof(echoServAddr));
第3章 メッセージの作成
3-1. データのエンコード
3-2 バイト順
ntoh
UDPEchoServer.cで、echoServAddr.sin_addr.s_addrをhtonl(INADDR_ANY)にしている
これはなに?
第4章 UDPソケット
UDPのメッセージについて
任意のアドレスから「複数の」アドレスへ(あるいは複数のアドレスから任意のアドレス)へ
UDPが接続を確立せずにメッセージを送信できることに起因する。
TCPの場合は1つのクライアントソケットで1対1の通信を行う。
UDPの場合は1つのクライアントソケットで、1対多の送信を行える。
UDPのソケットはそもそも、「決まった通信相手」という概念が存在しない
通信ごとに相手が変わり得るので、あらゆる送受信には必ず通信相手の情報が伴う設計。
まとめると
TCPクライアント
接続の確立
自身のソケットディスクリプタと、接続先アドレスをconnect()に渡す。
送信時
自身のソケットディスクリプタをsend()に渡す。
送信先アドレスは接続確立時に決まっているので渡す必要がない。
受信時
自身のソケットディスクリプタをrecv()に渡す。
受信元アドレスは接続確立時に決まっているので受け取る必要がない。
UDPクライアント
接続の確立
しない。どの相手への通信でも同じソケットを使い回せる。
送信時
自身のソケットディスクリプタと、送信先アドレスをsendto()に渡す。
受信時
自身のソケットディスクリプタと、受信元アドレスを受け取るためのバッファポインタをrecvfrom()に渡す。
TCPはソケットごとに誰と誰が通信するか決まっている
UDPはソケットに対して通信相手が決まっていない
5-1
ミスを見つけたかもしれない
どちらの場合も、$ optLenにはバッファへのポインタを指定します。
直前に示されているインターフェースでは、setsockoptの方はポインタではない
code: example_optLen.c
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvBufferSize, sizeof(rcvBufferSize)) < 0)
DieWithError("setsockopt() failed");
引数
int socket
sock
int level
int optName
void *optVal
rcvBufferSize
unsigned int optLen
sizeof(rcvBufferSize)
ミスっぽいな、これ
なぜgetsockoptのoptLenはポインタなのか。
この関数は、次の2つの値を返す必要がある。
ソケットオプションの値
ソケットオプションの長さ
複数の値を返したいので、ポインタにするしかない。
setsockoptの場合は、ソケットオプションの長さを返す必要はないので、ポインタにしなくとも問題ない。
非同期なソケットでサーバーとやり取り?
5.3.1
5-3 ノンブロッキングIOでは、ソケット呼び出し(recvfrom)が常に処理をブロッキングしてしまう問題を解消する。 そのために、
メッセージを関数呼び出しではなくシグナルを使って待機する。
5-4 マルチタスクでは、TCPで複数のソケットを同時にエコーできない問題を解消する。
シングルスレッドで動作しているのが原因。
対処
プロセスとは異なり、親とアドレス空間を共有する
メモリをコピーする必要がない
資源を削減できる
5