0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

SOCKET-MANAGER Frameworkでは、TCP通信(コネクション指向型)とUDP通信(コネクションレス型)の通信方式の違いを吸収するため、それぞれの接続を共通のディスクリプタ(クライアント接続子)で管理しています。

そのため、通信データの送受信を担うUNITパラメータクラスのメソッドは、TCP/UDP通信の区別なく同じインターフェースで利用できます。

但し、エントリポイントであるメイン処理クラスでのコネクション処理と待ち受けポートの設定に関しては明確に区別する必要があるため、ソケットリソースの消費が抑えられる静的セッション管理をベースとして処理を区別しています。

以降では待ち受けポートの設定とコネクション処理に分けて、それぞれのシグネチャを見ていきます。

待ち受けポートの設定

シグネチャ(TCP通信用)
メソッドlisten(?string $p_host = null, ?int $p_port = null): bool

パラメータ
    $p_host - ?string - 任意 - ホスト名デフォルトは"127.0.0.1"
    $p_port - ?int    - 任意 - ポート番号デフォルトは10000

戻り値booltrue:成功false:失敗
シグネチャ(UDP通信用)
メソッドbind(?string $p_host = null, ?int $p_port = null): bool

パラメータ
    $p_host - ?string - 任意 - ホスト名デフォルトは"127.0.0.1"
    $p_port - ?int    - 任意 - ポート番号デフォルトは10000

戻り値booltrue:成功false:失敗

コネクション処理

シグネチャ(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    - 必須 - ポート番号
    $p_udp      - bool   - 任意 - "UDP"接続フラグtrue:"UDP"接続false:"TCP"接続)。デフォルトはfalse
    $p_retry    - int    - 任意 - リトライ回数デフォルトは0無限
    $p_interval - int    - 任意 - リトライ間隔μs)。デフォルトは1000

戻り値booltrue:成功false:失敗

UDP通信の場合は、実際にコネクションを確立するわけでありませんが、共通のディスクリプタを生成するためにコールする必要があります。

UDP通信のハンドシェイク

以下のフローは、本フレームワーク内で提供される bind()/connect() メソッドを使った場合の一例ですが、UDPの通信原則に基づいて構成されているため、他の端末や独自実装のクライアントからの接続でも同様の手順で問題なく動作します。

UDP通信のハンドシェイクフロー

この通信モデルでは、クライアントが最初に空のパケットを送信することで、サーバー側に接続の意志を伝えます。

サーバーはこのパケットの送信元情報をもとに仮想的な接続状態(ディスクリプタ)を生成し、応答として空パケットを返すことでハンドシェイクが完了します。

以降、クライアントはこの応答を受信した時点でサーバーの接続情報を保持し、双方向のデータ通信を開始します。

この接続情報を取得する部分は、C言語での典型的な recvfrom() 関数の使い方に例えるとイメージしやすいでしょう。

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アドレスやポートが格納されている

このように、サーバーは空パケットを受信するだけで、送信元のIPアドレスとポート番号を把握できるため、仮想的な接続識別子(ディスクリプタ)を生成し、通信状態を管理する基盤を構築できます。

この処理を抽象化し、プロトコルに依存しない形式で実装できるのが本フレームワークの特徴のひとつです。

UDP通信にはTCPのような接続確立処理(accept)は存在しませんが、本フレームワークでは独自のハンドシェイク処理が完了した直後に、TCP通信と同様に accept ハンドラが自動的に呼び出されます。そのため、接続判定や認証シーケンスをプロトコルに依存せず統一的に実装できます。

おわりに

TCP通信では、接続時にOSレベルでハンドシェイクが自動的に行われ、接続確立後には accept ハンドラを通じて認証処理などを実装することができます。

本フレームワークでは、UDP通信においても同様の開発体験を提供することで、プロトコルに依存しない統一的な接続制御とアプリケーション設計を実現しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?