C言語-ソケットプログラミング_UDPソケット

UDP(User Datagram Protocol)ソケットについて

データグラム(Datagram)とは

データグラムとは、ネットワーク通信において、宛先アドレスなどの制御情報を付加されたデータのことです。


パケット(packet)とほぼ同じ意味ですが、制御有無により区別されます。

パケットは、TCP/IPなどで、再送制御や受信順の保証などが行われる信頼性の高い通信プロトコルにおけるデータの送受信単位のことを指します。

データグラムは、制御が行われない単純なプロトコルにおけるデータの送受信単位のことを指します。


UDPの特徴

UDPは、一方的にメッセージを送る、メッセージ指向型のプロトコルです。

TCPに比べて通信エラーへの耐性は低く、信頼性は高くありませんが、スピードやリアルタイム性が求められる通信に向いています。

また、コネクションレスであるため、複数の相手に同時にデータを送信するマルチキャスト通信やブロードキャスト通信にも適しています。

例えば、DNSサーバへのリクエスト、DHCPリクエスト、時刻合わせのNTP、ネットワーク機器の管理に使用されるSNMP等が挙げられます。


UDPソケットの機能

UDP(User Datagram Protocol)の機能は以下の2点です。

・UDPソケットの通信は、接続を確立しなくても使用することができる。

・転送中にデータ破損した場合、破損したデータグラムを破棄する。


UDPソケットは作成後すぐにメッセージの送受信を行うことができます。

メッセージは任意のアドレスから複数のアドレスへ連続的に送ることが可能です。


UDPソケットのクライアント処理

1.ソケットの生成

socket()関数でUDPフラグを指定します。


sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

2.サーバのアドレス構造体を作成する

接続先サーバのIPアドレスとポート番号を指定します。


struct sockaddr_in sv_addr;

memset(&sv_addr, 0, sizeof(sv_addr));
sv_addr.sin_family = AF_INET;
sv_addr.sin_addr.s_addr = inet_addr(<サーバのIPアドレス>);
sv_addr.sin_port = htons(<サーバのポート番号>);

3.データを送信する

UDP通信時(コネクションレス型のデータ転送時)にデータ送信ではsendto()関数を用います。


int sendto( int socket, const void *msg, unsigned int msgLength,
            int flags, struct sockaddr *addr_dest, unsigned int addrlen );

引数には以下を指定します。

socket ソケットディスクリプタを指定します。
msg 送受信するメッセージ領域を指定します。
msgLength メッセージの文字列長を指定します。
flags ソケットが呼び出された際のデフォルト動作を変更します。flagに「0」を指定するとデフォルト動作となります。
addr_dest 送信の宛先アドレス
addrlen アドレス長

戻り値は以下の通りです。

正常時 送受信したバイト数を返します。
エラー -1を返します。

UDPソケットのサーバ処理

1.ソケットの生成

socket()関数でUDPフラグを指定します。


sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);

2.サーバのアドレス構造体を作成する

サーバ側の待受IPアドレスとポート番号を指定します。

明示的に利用するネットワークインターフェースを指定しない場合には、INADDR_ANYを指定します。


struct sockaddr_in sv_addr;

memset(&sv_addr, 0, sizeof(sv_addr));
sv_addr.sin_family = AF_INET;
sv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
sv_addr.sin_port = htons(<サーバのポート番号>);

3.ローカルアドレスへバインドする

bindシステムコールは、ソケットに名前(ポート番号 & IPアドレス)を付けます。


#include<sys/types.h>
#include<sys/socket.h>

int bind(int socket, const struct sockaddr *address, size_t address_len);

戻り値が失敗(-1)の場合のerrnoにエラーの原因値が格納されます。


4.データを送信する

UDP通信時(コネクションレス型のデータ転送時)にデータ送受信ではrecvfrom()関数を用います。

クライアントからメッセージを受信するまでブロックする動作となります。


int recvfrom( int socket, void *msg, unsigned int msgLength,
            int flags, struct sockaddr *addr_src, unsigned int *addrlen );

引数には以下を指定します。

socket ソケットディスクリプタを指定します。
msg 送受信するメッセージ領域を指定します。
msgLength メッセージの文字列長を指定します。
flags ソケットが呼び出された際のデフォルト動作を変更します。flagに「0」を指定するとデフォルト動作となります。
addr_src 受信の宛先アドレス
addrlen アドレス長

戻り値は以下の通りです。

正常時 送受信したバイト数を返します。
エラー -1を返します。

関連ページ


UDP通信


TCP通信