用途によってコネクションを確立しなくても、場合によってメッセージの欠 落が起こっても問題にならない通信の方法もありえます。定期的な情報の発信 で、一つくらい届かなくても次ので十分なものなどです。また一回のメッセー ジ送信で必要な情報が完結する場合などがあてはまります。ですからネットワー ク同報通信もデータグラム型では可能です。
データグラム型もソケット通信を用いていますからソケットの開設のところ はストリーム型ソケット通信と同じです。
#include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> int fd, len, sbsize; struct sockaddr_in sa, sb; struct hostent *hp; /* データグラムソケット*/ fd = socket( PF_INET, SOCK_DGRAM, 0 ); hp = gethostbyname( "yaoya" ); /* サーバの名前 */ sa.sin_family = AF_INET; /* アドレスファミリーはAF_INET */ sa.sin_port = htons( 10002 ); /* サーバのポート番号 */ sa.sin_addr.s_addr = *( unsigned long * ) ( * hp -> h_addr_list ); /* メッセージごとにアドレスを指定 */ len = strlen( buf ); sendto( fd, buf, len, 0, ( struct sockaddr * ) &sa, sizeof( sa ) ); /* recvも送り手のアドレスを受け取れるように */ sbsize = sizeof( sb ); recvfrom( fd, buf, sizeof( buf ), 0, ( struct sockaddr * ) &sb, &sbsize ); close( fd );
ソケットをデータグラムソケットとしてインターネットアドレスファミリーに 対して開きます。ソケットに対して直接アドレスを与えて送信・受信します。
サーバ側ではsocketシステムコールの後に、クライアントから参照できるよ う自分のポート番号を固定するためにbindシステムコールが必要です。変数宣 言などはクライアントと同じとして、
/* データグラムソケット */ fd = socket( PF_INET, SOCK_DGRAM, 0 ); /* だれからのデータでも受け取る*/ sa.sin_family = AF_INET; sa.sin_port = htons( 10002 ); sa.sin_addr.s_addr = INADDR_ANY; bind( fd, ( struct sockaddr * ) &sa, sizeof( sa ) ); /* 受信のための無限ループ */ while( loop ) { sbsize = sizeof( sb ); recvfrom( fd, buf, sizeof( buf ), 0, ( struct sockaddr * ) &sb, &sbsize); /* ここでreplyを用意してクライアントに送り返す*/ sendto( fd, reply, strlen( reply ), 0, ( struct sockaddr * ) &sb, sbsize ); } close( fd );
AF_UNIXアドレスファミリーと同じシステムコールを使うのでソケットアドレ ス構造体をキャストしてやる必要があります。サーバの時受信するまで相手の アドレスはわかりません。recvfromのなかでsbに相手のアドレスが返されます。 それへの応答はsbを相手のアドレスとして使ってsendtoを呼び出します。
クライアントから見てもコネクションを張るわけではないのでデータを誰か に受け取ってもらえばよいという立場が取れます。いわゆる同報通信ブロード キャストが可能です。ポート番号は指定しますが、相手型アドレスに INADDR_ANYを置きます。