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"); } }