-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtcp-and-udp.html
More file actions
327 lines (248 loc) · 19 KB
/
tcp-and-udp.html
File metadata and controls
327 lines (248 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>TCP/UDP通信について | SOCKET-MANAGER Framework For PHP</title>
<meta name="description" content="SOCKET-MANAGERフレームワークでのTCP/UDP通信の使い分けの方法を解説。UNITの実装例を具体的に紹介。" />
<meta content="PHP,ソケット通信,サーバー開発,framework,TCP,UDP,ソケットマネージャー" name="keywords">
<link rel="canonical" href="https://socket-manager.github.io/document/tcp-and-udp.html" />
<script async src="https://www.googletagmanager.com/gtag/js?id=G-LF9W695NNW"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-LF9W695NNW');
</script>
<link rel="icon" href="https://socket-manager.github.io/document/favicon.ico" type="image/x-icon" />
<link type="text/css" rel="stylesheet" href="./css/common.css" media="all" />
<script src="./js/jquery-3.7.1.min.js"></script>
<script type="text/javascript" src="./js/common.js"></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "SOCKET-MANAGER Framework - TCP/UDP通信の実装ガイド",
"description": "SOCKET-MANAGERフレームワークにおけるイベントハンドラの実装方法を解説。キューとステータスUNITを使った非同期処理、再利用UNIT、ポーリングUNIT、リトライUNITの実装例を具体的に紹介。",
"image": "https://socket-manager.github.io/document/minecraft-contents/img/tcp-and-udp/udp-flow.png",
"articleSection": ["Technical Documentation", "Server Development", "PHP Programming"],
"keywords": "PHP,ソケット通信,サーバー開発,framework,TCP,UDP,ソケットマネージャー",
"author": {
"@type": "Person",
"name": "SOCKET-MANAGER開発チーム"
},
"publisher": {
"@type": "Organization",
"name": "SOCKET-MANAGER",
"logo": {
"@type": "ImageObject",
"url": "https://socket-manager.github.io/document/logo.png",
"width": 355,
"height": 50
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://socket-manager.github.io/document/tcp-and-udp.html"
},
"url": "https://socket-manager.github.io/document/tcp-and-udp.html",
"breadcrumb": {
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"name": "Framework Top",
"item": "https://socket-manager.github.io/document/"
},{
"@type": "ListItem",
"position": 2,
"name": "イベントハンドラについて",
"item": "https://socket-manager.github.io/document/tcp-and-udp.html"
}]
},
"isPartOf": {
"@type": "WebSite",
"name": "フレームワークのご紹介",
"url": "https://socket-manager.github.io/document/"
}
}
</script>
</head>
<body>
<div class="layout">
<div class="menu" role="navigation" aria-label="ページメニュー">
<h2 class="menu-title">SOCKET-MANAGER</h2>
<h4 class="menu-reference menu-page-title-bottom"><a href="./reference/" target="_blank">>> Reference</a></h4>
<h2 class="menu-label">MAIN-MENU</h2>
<div class="menu-text">
<h3 class="menu-page-title-link"><a href="./">▶フレームワークのご紹介</a></h3>
<h3 class="menu-page-title-link"><a href="./event-handler.html">▶イベントハンドラについて</a></h3>
</div>
<h3 class="menu-label-sub">IMPLEMENT</h3>
<div class="menu-text">
<h3 class="menu-page-title-link"><a href="./init-class.html">▶初期化クラス</a></h3>
<h3 class="menu-page-title-link"><a href="./unit-parameter.html">▶UNITパラメータクラス</a></h3>
<h3 class="menu-page-title-link"><a href="./protocol-unit.html">▶プロトコルUNITクラス</a></h3>
<h3 class="menu-page-title-link"><a href="./command-unit.html">▶コマンドUNITクラス</a></h3>
<h3 class="menu-page-title-link"><a href="./main.html">▶メイン処理クラス</a></h3>
<h3 class="menu-page-title-link"><a href="./setting.html">▶設定ファイル</a></h3>
<h3 class="menu-page-title-link"><a href="./message.html">▶メッセージファイル</a></h3>
</div>
<div class="menu-line"></div>
<div class="menu-text">
<h3 class="menu-page-title-link-for-runtime-manager"><a href="./runtime-manager/" target="_blank">>> ランタイムライブラリ</a></h3>
<h3 class="menu-page-title-link-for-runtime-manager"><a href="./simple-socket/" target="_blank">>> シンプルソケット機能</a></h3>
</div>
<h3 class="menu-label-sub">ADVANCED</h3>
<div class="menu-text">
<h3 class="menu-page-title-link"><a href="./concept.html">▶設計コンセプト</a></h3>
<h3 class="menu-page-title-link"><a href="./architecture.html">▶アーキテクチャ</a></h3>
<h3 class="menu-page-title-link"><a href="./communication.html">▶通信抽象化</a></h3>
<h3 class="menu-page-title-link"><a href="./union.html">▶共有基盤</a></h3>
<h3 class="menu-page-title-link"><a href="./event.html">▶イベント駆動アーキテクチャ</a></h3>
<h3 class="menu-page-title-link"><a href="./ipc.html">▶IPC(プロセス間通信)</a></h3>
<h3 class="menu-page-title-link"><a href="./multi-server.html">▶マルチサーバーの構成</a></h3>
<h3 class="menu-page-title">▼TCP/UDP通信について</h3>
<ul>
<li><a href="./tcp-and-udp.html#begin">はじめに</a></li>
</ul>
<ul>
<li><a href="./tcp-and-udp.html#await">待ち受けポートの設定</a></li>
</ul>
<ul>
<li><a href="./tcp-and-udp.html#connection">コネクション処理</a></li>
</ul>
<ul>
<li><a href="./tcp-and-udp.html#handshake">UDP通信のハンドシェイク</a></li>
</ul>
<ul>
<li><a href="./tcp-and-udp.html#last">おわりに</a></li>
</ul>
<h3 class="menu-page-title-link"><a href="./laravel.html">▶Laravelと連携する</a></h3>
<h3 class="menu-page-title-link"><a href="./system-setting.html">▶システム設定ファイル</a></h3>
<h3 class="menu-page-title-link"><a href="./custom-command.html">▶カスタムコマンド作成機能</a></h3>
<h3 class="menu-page-title-link"><a href="./high-performance.html">▶ハイパフォーマンスモード</a></h3>
<h3 class="menu-page-title-link"><a href="./scale-test.html">▶実運用スケールベンチマーク</a></h3>
<h3 class="menu-page-title-link"><a href="./itil.html">▶技術版 ITIL としての CUEI/O</a></h3>
</div>
<h3 class="menu-label-sub">OTHER-PROJECT</h3>
<div class="menu-text">
<h3 class="menu-page-title-link"><a href="./new-project.html">▶新規開発環境</a></h3>
<h3 class="menu-page-title-link"><a href="./websocket.html">▶Websocketサーバー開発環境</a></h3>
<h3 class="menu-page-title-link"><a href="./dev-ops.html">▶フレームワークのDevOps環境</a></h3>
</div>
<div class="menu-line"></div>
<div class="menu-text">
<h3 class="menu-page-title-link-for-minecraft"><a href="./minecraft-contents/" target="_blank">>> マインクラフト専用環境</a></h3>
<h3 class="menu-page-title-link-for-launcher"><a href="./launcher/" target="_blank">>> GUI & CLI ランチャー</a></h3>
<h3 class="menu-page-title-link-for-rest-api"><a href="./rest-api/" target="_blank">>> REST-APIサーバー開発環境</a></h3>
</div>
<h2 class="menu-label">EXTRA-MENU</h2>
<div class="menu-text">
<h3 class="menu-page-title-link"><a href="./extra-demo.html">▶デモサーバーの種類</a></h3>
<h3 class="menu-page-title-link"><a href="./extra-demo-command.html">▶デモのコマンド仕様</a></h3>
<h3 class="menu-page-title-link"><a href="./extra-demo-setting.html">▶デモの設定ファイル</a></h3>
<h3 class="menu-page-title-link"><a href="./extra-minecraft.html">▶マインクラフトの通信仕様</a></h3>
<h3 class="menu-page-title-link"><a href="./extra-close-frame.html">▶切断フレームの検証</a></h3>
</div>
<h2 class="menu-label">PHP-TECHNIQUE</h2>
<div class="menu-text">
<h3 class="menu-page-title-link"><a href="./php-pass-by-reference.html">▶参照渡し</a></h3>
<h3 class="menu-page-title-link"><a href="./php-phpdoc.html">▶PHPDocのフォーマット</a></h3>
</div>
<div class="menu-dummy-for-framework"></div>
</div>
<div class="main" role="main">
<h1>【TCP/UDP通信について】</h1>
<a id="begin"></a>
<h2 class="subtitle">はじめに</h2>
<div class="text-block">
SOCKET-MANAGER Frameworkでは、TCP通信(コネクション指向型)とUDP通信(コネクションレス型)の通信方式の違いを吸収するため、それぞれの接続を共通のディスクリプタ(クライアント接続子)で管理しています。そのため、通信データの送受信を担うUNITパラメータクラスのメソッドは、TCP/UDP通信の区別なく同じインターフェースで利用できます。<br /><br />
但し、エントリポイントであるメイン処理クラスでのコネクション処理と待ち受けポートの設定に関しては明確に区別する必要があるため、ソケットリソースの消費が抑えられる静的セッション管理をベースとして処理を区別しています。<br /><br />
以降では待ち受けポートの設定とコネクション処理に分けて、それぞれのシグネチャを見ていきます。<br />
</div><br />
<a id="await"></a>
<h2 class="subtitle">待ち受けポートの設定</h2>
<div class="text-block">
シグネチャの青字の部分は省略できるパラメータを表しています。<br />
<pre aria-label="シグネチャ(TCP通信用)">
【メソッド】listen(?string $p_host = null, ?int $p_port = null): bool
【パラメータ】
<font class="pre-type">
$p_host - ?string - 任意 - ホスト名。デフォルトは127.0.0.1
$p_port - ?int - 任意 - ポート番号。デフォルトは10000
</font>
【戻り値】bool(true:成功、false:失敗)
</pre>
<pre aria-label="シグネチャ(UDP通信用)">
【メソッド】bind(?string $p_host = null, ?int $p_port = null): bool
【パラメータ】
<font class="pre-type">
$p_host - ?string - 任意 - ホスト名。デフォルトは127.0.0.1
$p_port - ?int - 任意 - ポート番号。デフォルトは10000
</font>
【戻り値】bool(true:成功、false:失敗)
</pre>
</div><br />
<a id="connection"></a>
<h2 class="subtitle">コネクション処理</h2>
<div class="text-block">
シグネチャの青字の部分は省略できるパラメータを表しています。<br />
<pre aria-label="シグネチャ(TCP/UDP共通)">
【メソッド】connect(string $p_host, int $p_port, bool $p_udp = false, int $p_retry = 0, int $p_interval = 1000): bool
【パラメータ】
$p_host - string - 必須 - ホスト名
$p_port - int - 必須 - ポート番号
<font class="pre-type">
$p_udp - bool - 任意 - UDP接続フラグ(true:UDP接続、false:TCP接続)。デフォルトはfalse
$p_retry - int - 任意 - リトライ回数。デフォルトは0(無限)
$p_interval - int - 任意 - リトライ間隔(μs)。デフォルトは1000
</font>
【戻り値】bool(true:成功、false:失敗)
</pre>
UDP通信の場合は、実際にコネクションを確立するわけでありませんが、共通のディスクリプタを生成するためにコールする必要があります。<br />
</div><br />
<a id="handshake"></a>
<h2 class="subtitle">UDP通信のハンドシェイク</h2>
<div class="text-block">
以下のフローは、本フレームワーク内で提供される bind()/connect() メソッドを使った場合の一例ですが、UDPの通信原則に基づいて構成されているため、他の端末や独自実装のクライアントからの接続でも同様の手順で問題なく動作します。<br /><br />
<div class="img-block">
<a href="./img/tcp-and-udp/udp-flow.png" target="_blank"><img class="img-zoomout" src="./img/tcp-and-udp/udp-flow.png" loading="lazy" alt="UDP通信のハンドシェイクフロー" /></a>
</div>
この通信モデルでは、クライアントが最初に空のパケットを送信することで、サーバー側に接続の意志を伝えます。<br />
サーバーはこのパケットの送信元情報をもとに仮想的な接続状態(ディスクリプタ)を生成し、応答として空パケットを返すことでハンドシェイクが完了します。<br />
以降、クライアントはこの応答を受信した時点でサーバーの接続情報を保持し、双方向のデータ通信を開始します。<br /><br />
この接続情報を取得する部分は、C言語での典型的な recvfrom() 関数の使い方に例えるとイメージしやすいでしょう。
<pre color-change="php" aria-label="C言語での接続情報の取得例">
struct sockaddr_in client_addr;
socklen_t addrlen = sizeof(client_addr);
char buffer[1];
// 空パケットの受信と同時に送信元アドレスを取得
recvfrom(server_socket, buffer, sizeof(buffer), 0,
(struct sockaddr *)&client_addr, &addrlen);
// ここで client_addr にIPアドレスやポートが格納されている
</pre><br />
このように、サーバーは空パケットを受信するだけで、送信元のIPアドレスとポート番号を把握できるため、仮想的な接続識別子(ディスクリプタ)を生成し、通信状態を管理する基盤を構築できます。この処理を抽象化し、プロトコルに依存しない形式で実装できるのが本フレームワークの特徴のひとつです。<br /><br />
UDP通信にはTCPのような接続確立処理(accept)は存在しませんが、本フレームワークでは独自のハンドシェイク処理が完了した直後に、TCP通信と同様に accept ハンドラが自動的に呼び出されます。そのため、接続判定や認証シーケンスをプロトコルに依存せず統一的に実装できます。<br />
<br />
<h3 class="underline">ハイパフォーマンスモード利用時の注意点(UDP)</h3>
<p>
ハイパフォーマンスモード(High Performance Mode)では、UDP 通信の疑似ハンドシェイク処理において<strong>ポート番号をペイロード部に含める追加仕様</strong>があります。<br /><br />
空パケットのペイロード先頭 2 バイト(ビッグエンディアン)にポート番号を格納する必要があり、クライアント側は自身の送信元ポート番号を、サーバー側は新たに割り当てたポート番号を返します。<br /><br />
以降の通信では、<strong>recvfrom() などで取得した送信元 IP アドレス</strong>と、<strong>ペイロード部に含まれるポート番号</strong>を組み合わせて送受信先を決定してください。<br />
これにより、ハイパフォーマンスモードにおける高速な UDP ディスクリプタ管理と、大量接続時の安定した通信制御が可能になります。
</p><br />
<p style="margin-top: 10px;">
▶ ハイパフォーマンスモードの設計思想とベンチマークはこちら: <a class="embedded-link" href="./high-performance.html">>> ハイパフォーマンスモード</a>
</p>
</div><br />
<a id="last"></a>
<h2 class="subtitle">おわりに</h2>
<div class="text-block">
TCP通信では、接続時にOSレベルでハンドシェイクが自動的に行われ、接続確立後には accept ハンドラを通じて認証処理などを実装することができます。<br />
本フレームワークでは、UDP通信においても同様の開発体験を提供することで、プロトコルに依存しない統一的な接続制御とアプリケーション設計を実現しています。<br />
</div>
</div>
</div>
</body>
</html>