UDOの場合は、メッセージの境界を保持する。UDPはエラーから回復を行わないため、再送信に備えてバッファーを保持することがない。UDPソケットからsendto()を実行して処理が戻った時点で下位の送信チャンネルにメッセージが渡されるため、このタイミングでバッファからデータが出ていく。受信側ではバッファのサイズを十分に大きくして、データの破棄がなくなるようにしている。
#include <stdio.h> /* printf(), fprintf()に必要 */
#include <sys/socket.h> /* socket(), bind(), connect()に必要 */
#include <arpa/inet.h> /* sockaddr_in, inet_ntoaに必要 */
#include <stdlib.h> /* atoi()に必要 */
#include <string.h> /* memset()に必要 */
#include <unistd.h> /* close()に必要 */
#define ECHOMAX 255 /* エコー文字列の最大長 */
void DieWithError(char *errorMessage); /* エラー処理関数 */
int main(int argc, char *argv[]){
int sock; /* ソケット */
struct sockaddr_in echoServAddr; /* ローカルアドレス */
struct sockaddr_in echoClntAddr; /* クライアントアドレス */
unsigned int cliAddrLen; /* 着信メッセージの長さ */
char echoBuffer[ECHOMAX]; /* エコー文字列用バッファ */
unsigned short echoServPort; /* サーバのポート番号 */
int recvMsgSize; /* 受信メッセージのサイズ */
if(argc != 2) { /* 引数が正しいかの確認 */
fprintf(stderr, "Usage: %s <Server Port\n>", argv[0]);
exit(1);
}
echoServPort == atoi(argv[1]); /* ローカルポート */
/* データグラムの送受信に使うソケットを作成 */
if((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* ローカルアドレス構造体を作成 */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* 構造体を0埋め */
echoServAddr.sin_family = AF_INET; /* インターネットアドレスファミリ */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* ワイルドカードを使用 */
echoServAddr.sin_port = htons(echoServPort); /* ローカルポート */
/* ローカルアドレスへのインバインド */
if(bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
DieWithError("bind() failed");
/* 無限ループ */
for(;;) {
/* 入出力パラメータのサイズをセット */
clntLen = sizeof(echoClntAddr);
/* クライアントからメッセージを受信するまでブロックする */
if((recvMsgSize = recvfrom(sock, echoBuffer, ECHOMAX, 0, (struct sockaddr *) &echoClntAddr, &cliAddrLen)) < 0)
DieWithError("recvfrom() failed");
printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
/* 受信したデータグラムをクライアントに返信する */
if(sendto(sock, echoBuffer, recvMsgSize, 0, (struct sockaddr *) &echoClntAddr, sizeof(echoClntAddr)) != recvMsgSize)
DieWithError("sendto() sent a different number of bytes than expected");
}
}