Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Tcpudpクライアント間通信

1,421 views

Published on

UDPホールパンチングの概念の解説

Published in: Technology
  • Be the first to comment

Tcpudpクライアント間通信

  1. 1. TCP/UDP Socket Client間通信 C#福岡 Vol.5 2014/8/7 K.Takahashi
  2. 2. はじめに • おかげさまでC#勉強会も1年を迎えることが できました。ありがとうございます。 • C#勉強会と言いつつも毎回結構脱線してる 気もしますが。 • これからはAzure方面も積極的に絡めていき たいですね(希望)
  3. 3. 展望とか展開とか • 9/20にはふくあずさん、WinTechqさんの誘い でMSのエバンジェリスト迎えた合同イベントも やりますよ。 • DotNetのくくりでF#なんかもかじりたいですよ ね。(でもVBはdisり続けたいですねw) • 8/20にもふくあずさんの勉強会あるからよろ しくね。
  4. 4. 前提的な話題をざっくりと • サーバがあるポート番号で待ってる (SSHなら22とかHTTPなら80とか) ・そこに向けてクライアントが通信する ・Connectした通信の経路が確保される ・あとはその経路を使ってやり取りする ⇒この流れのI/FがSocket
  5. 5. TCPとUDPを例えると • TCP:Transmission Control Protocol – 受け取り時にハンコが必要な書留みたいな – 不在通知は残さないけど再配達に来てくれる – 再配達の回数やタイムアウトを指定できる • UDP:User Datagram Protocol – ポストに放り込んでおわり – ポストがなくなってたら適当に捨てる
  6. 6. • 当然TCPよりUDPのほうが処理が軽い • じゃあ、コマンドとか通知系はTCPで • 間が抜けてもなんとかなるデータはUDPで (ちなみにFTPなんかは自前でリトライしてます)
  7. 7. FireWall(NAT) HTTP SV A.B.C.D:80 AA.B.C.D:80 さま データくれ 192.168.1.10:80 Router W.X.Y.Z AA.B.C.D:80 さま データくれ W.X.Y.Z:10325 AA.B.C.D:80 さま データくれ W.X.Y.Z:10326 AA.B.C.D:80 さま データくれ 192.168.1.11:80 NATから外に出る時に任意・一意 のポート番号に振り替える サーバからの応答はポート番号か ら逆引きで返送先のローカルPCを 特定するのに使われる
  8. 8. UDPホールパンチング CTRL SV UDP:A.B.C.D:200 A.B.C.D:200 さま お話しようぜ 192.168.1.10:200 A.B.C.D:200 さま お話しようぜ W.X.Y.Z:11551 あいつ W.X.Y.Z:11551で話 せるらしいぜ TCPで確立 済の通信 W.X.Y.Z:11551さん やあ、オレオレ 192.168.1.5:200 192.168.1.10:200さん やあ、オレオレ K.L.M.N:10856 会話成立! TCPではSVに送ったら受取通知が SVから返るので騙せない UDPはSVから受取通知が返らない ので他のPCが通信相手になりすま せる
  9. 9. • サーバ側の受信はこんな感じ public static ManualResetEvent allDone = new ManualResetEvent(false); (略) // Create a TCP/IP socket. IPEndPoint localEndPoint = new IPEndPoint(ipAddress, receivePort); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Bind the socket to the local endpoint and listen for incoming connections. listener.Bind(localEndPoint); listener.Listen(100); while (bReceiveContinue) { // Set the event to nonsignaled state. allDone.Reset(); if (listener == null) break; // Start an asynchronous socket to listen for connections. listener.BeginAccept( new AsyncCallback(AcceptCallback), listener); // Wait until a connection is made before continuing. allDone.WaitOne(); }
  10. 10. • UDP送受信はこんな感じ サーバに自分のUDPデータを送るとTCPで通知(TCPSocket) サーバに自分のUDPデータを送る(UDPSocket) ※サーバから変換後のUDPポートをTCPで相手に通知 UDPホールパンチングで通信相手からUDPが来るのを待つ (UDPClient.BeginReceive) ※片方がUHP対策されているルータに守られていることもあるので 両方からホールパンチングを投げ合うと成立しやすい 成立後は通信相手と本ちゃんデータを投げ合う(UDPClient.Send)
  11. 11. 最後に ・・・・あんまりC#に特化してなかった気がする

×