UDP通信メモ

iPhone用にwifi接続のゲームパッドアプリを作ってみた。
その際にUDP通信を使ったので、それに関するメモを少々書いとく。

[TCP]
1対1の通信を確実に行うことに適する。
サーバーとクライアントと別れ、通信待機中(Listen)のサーバーにクライアントから接続(Connect)を行って始めて通信可能になる。互いの存在を確認しながら通信を行うので、相手が通信を終了したらもう片方はそれを検出できる。プロトコルとして、データ欠損時の自動再送とデータ順序の整理が含まれているため、アプリケーション側はそれらを意識することなく通信することができる。

[UDP]
1対Nの通信に適している。
コネクションの確立が不要であり、あて先とポート番号さえ決めれば決めれば送出が可能である。相手が実際に存在せずともエラーにはならない。自動再送とデータ順序の整理を含まないシンプルなプロトコルであり、アプリケーションはこれらの発生を考慮しなければならない。互いのデータのやり取りに確認処理が生じないためにオーバーヘッドが小さく、リアルタイム性の高い通信が可能である。


リアルタイム性からネット対戦なんかにはUDP通信が使われることが多い。しかし順序のズレ、データ欠損が発生する可能性があるため、それに耐えれる仕組みをいれる必要がある模様。その分コード量が増え、見かけ上複雑になることがある。アプリケーション側により再送命令などをUDPで実現することも可能だが、ヘタなことをやるとTCP以下のパフォーマンスがでない。UDPの投げっぱなし通信をうまく利用する必要がある。


[UDP送信側]




//送りたいデータ
int data = 1;

//ソケットの作成
int sock = socket(AF_INET, SOCK_DGRAM, 0);

//あて先
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(6788);
addr.sin_addr.s_addr = inet_addr("192.168.1.8");

socklen_t addr_size = (socklen_t)sizeof(struct sockaddr_in);

//送信
sendto(sock, &data, sizeof(int), 0, (struct sockaddr*)&addr, addr_size);




192.168.1.8の6788ポートにint型の数値1を送信するだけならこれだけ短い。
sendtoは引数にあて先を指定する。TCPのsendは事前に通信相手が確定するため、その引数はない。
送信だけならbindの必要もない。


[UDP受信側]




//受信データ
int data = 0;

//ソケットの作成
int sock = socket(AF_INET, SOCK_DGRAM, 0);

//受信アドレス
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(6788);
addr.sin_addr.s_addr = INADDR_ANY;
socklen_t addr_size = (socklen_t)sizeof(struct sockaddr_in);

//送信元アドレス格納先
struct sockaddr_in addr2;
socklen_t addr_size2;

//ソケットのバインド
bind(sock, (struct sockaddr*)&addr, addr_size);

//受信
recvfrom(sock, &data, sizeof(int), 0, (struct sockaddr*)&addr2, &addr_size2);




すべてアドレスから届く6788ポートへのデータを受信する。
受信時はそのポートを監視しないといけないためバインドが必要になる。
recvfromでは引数に送信元データの格納先を指定してやることで、どこからの通信なのか調べることができる。ただしいデータが入っていないことがある。


(貼ってあるコードは実際に動作したコードが元になっているものの、ブログ用にある程度適当に切り貼りしたものでそのまま動くかはわかりません。)
Go To 物置。
プロフィール

書いてる人:つん

まったりのんびり。書いてる人の息抜きブログです。

多分連絡先↓
[email protected]

カテゴリー
リンク
月別アーカイブ
バロメーター
Java歴:2005年2月から今まで。
3DCG歴:2005年8月から数年。
C歴:2006年4月から今まで。
VB歴:2007年3月からちょっと。
Delphi歴:2007年3月からちょっと。
PIC歴:2007年5月から数年。
イラスト歴:2007年12月から今まで。
DTM歴2008年2月からちょっと。
PHP歴2008年4月からちょっと。
C++歴2008年4月から今まで。
C#歴2009年1月から今まで。
Objective-C歴2009年4月から今まで。
CSS歴2012年5月から今まで。

ブログ開始日2005/10/11