UDPとTCPと
UDPソケットプログラミングをしていて、ちょっといろいろとはまってしまったので、
それについてまとめてみました。
普通、ネットワークについて勉強していると、トランスポート層の例としてUDPとTCP
が出てきて、
って習いますよね。例えば、
https://www.itbook.info/study/tcp3.html
で解説されているような感じ。
だから、TCPはコネクションを張ってから安全にストリームをやりとり、UDPはコネクションを
用いずいきなりデータグラムを飛ばす、、というイメージ。
ところが、UDPのライブラリを見ると、必ず「connect」というメソッドが出てきます。あれ?
UDPってコネクションレスなのに、どうしてconnect?
Stackoverflowとかで、UDPのコネクションについての質問とかみると、よく「UDPはコネクションレスだ。
お前の言っているコネクションの定義は?」みたいなコメントがついているけど、、、、
というか、調べると普通に載っていて、例えば
http://www.asahi-net.or.jp/~aa4t-nngk/ipttut/output/udpconnections.html
な〜んだ、コネクションあるじゃん、、。
とはいえ。
それでもUDPではコネクションを使うのは一般的ではないらしい。そして、上のサイトにもあるように、
UDPコネクションは、スレートレスなコネクションであって、「接続の確立」「クローズ」といったものも
ないようだ。
じゃあ意味ないの?
いや、すごい大切な意味があるのです。(たぶん)
というのも、UDPは、データグラムを送りっぱなしの仕組みなので、そもそもデータを受け取る相手が
本当にいるのかどうかよくわからないプロトコルです。
データを受け取る側の実装がよく分かっていれば問題ないのですが、一般的には、相手がデータを受け取る
準備ができているのかどうかよく分からない、、。
そんな時、コネクションを使うとよいようです。コネクションを張った状態で、ダミーのデータを送り、
そしてデータの読み取りをすると、
1. 相手が存在する場合は、何らかのデータを返してくるか、もしくは無反応。
2. 相手が存在しない場合は、ICMP Unreachableエラー
になります。このICMP Unrechableエラー(パケットキャプチャしてればこれがちゃんと送られてくる
はずなのだけど、送り側まで届くのかは不明。でもまあ、GCDAsyncUdpSocketライブラリでは、少なくと
も強制的にNetwork closedされる)を得られることが大切であって、これでデータを受け取る相手が存在
するかしないかを判定することが出来ます。
あ、、、もしかしたら、コネクションを張らないでも、他に方法があるのかも知れませんが、、。
僕はいろいろ頑張ってみたものの、コネクションを張ることでうまく出来たので、これでヨシとしました。
あまりネットワークに強くないので、このあたりのプログラミングは気を使います。
もっと良い方法をご存知の方がいれば、ご教示いただきたいです。