Linux での UDP について学ぶ

Linux での UDP について学ぶ

1. UDP と Linux の基礎の紹介

ソケット: IPアドレス + ポート番号

IPアドレス: 4バイト ポート番号: 2バイト、つまり範囲は0〜65535
ポート番号は、よく知られているポート番号、いくつかの固定ポート番号、およびよく知られているポート番号に分けられます。
0~1023: http、ssh、ftp、telnet などのプロトコルのポート番号は固定されており、オペレーティング システムによって割り当てることはできません。

いくつかの固定ポート番号

SSH サーバー、ポート 22 を使用
FTP サーバー、ポート 21 を使用
Telnet サーバー、ポート 23 を使用
http サーバー、ポート 80 を使用
HTTPS サーバーはポート 443 を使用します。オペレーティング システムによって動的に割り当てられるポート番号は、クライアント サーバーのポート番号です。オペレーティング システムは、この範囲のポート番号を割り当てることができます。

ポート番号を確認する

/etc/services を減らす
 //Linuxではすべてのポート番号を表示できます

IP アドレスの理解:
IP アドレスはホストを識別するために使用されます。

ポート番号の理解:
ポート番号は、オペレーティング システムにどのプロセスを操作するかを伝えるために使用されます。つまり、ポート番号はプロセスを識別するために使用されます。ポート番号は 1 つのプロセスのみが占有できますが、プロセスは複数のポート番号を持つことができます。つまり、プロセスとポート番号は 1 対多の関係です。ポート番号を使用してプログラムを作成するときは、これらのよく知られているポート番号を避ける必要があります。

【質問】

(1)プロセスは複数のポート番号にバインドできますか?
はい、プロセスは複数のファイル記述子を開くことができ、各ファイル記述子はポート番号に対応しているため、プロセスは複数のポート番号をバインドできます。

(2)ポート番号を複数のプロセスでバインドできますか?
いいえ。プロセスが最初にポート番号をバインドし、次に子プロセスをフォークすると、複数のプロセスを 1 つのポート番号にバインドできます。ただし、異なるプロセスを同じポート番号にバインドすることはできません。
TIME_WAIT 状態では、サーバーをすぐに再起動することはできません。つまり、異なるプロセスが同時に同じポート番号にバインドすることもできません。

(3)複数のプロセスが同じポート番号をリッスンできますか?
できる。リッスンする前に、ソケット -> bind ip::port number -> listen を作成する必要があります。 bind の前に setsockopt 関数を使用して、REUSEADDR オプションを含むソケット オプションを設定できます。REUSEADDR オプションは、bind 関数で指定されたアドレスとポート番号を複数のプロセスが再利用できることを示します。したがって、ソケットはホスト上のプロセスを正確に識別し、コンピューター間の通信を完了できます (ホスト A 上のプロセスがホスト B 上の別のプロセスと通信します)。

ネットワークバイトオーダー変換:
データがネットワーク内で送信される場合、独自の送信ルールがあります。ホスト上のデータには 2 つの送信シーケンスがあります。
ビッグエンディアン: 上位バイト順が下位アドレスに配置されます。リトルエンディアン: 下位バイト順が下位アドレスに配置されます。送信: 下位アドレスのデータが最初に送信され、次に上位アドレスのデータが送信されます。そのため、ホストからネットワークにデータが送信されると、データエラーが発生する可能性があります (たとえば、ホストがリトルエンディアンの場合は変換が必要です)。

変換機能:

uint32_t htonl(uint32_t ホストロング);
uint16_thtons(uint16 ホストショート);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t ネットショート);
h: ホスト名を示す
n: ネットワークを示す
l: 4バイト長を示す
s: 2バイトの短い文字列を示す

アドレス変換機能:

文字列をin_addrに変換する
in_addr_t inet_addr(const char* strptr)
in_addrは文字列に変換されます char* inet_ntoa(struct in_addr inaddr)

この関数自体が IP アドレス文字列を格納するためのスペースを静的領域に割り当てるため、再入不可能、つまり複数回呼び出すことはできません。

UDP プロトコル:
UDPプロトコル終了フォーマット

  • 16はUDP長で、データグラム全体の最大長(UDPヘッダー+UDPデータ)(64KB)を示します。
  • チェックサム: チェックサムが間違っている場合は、そのまま破棄されます (チェックはヘッダーとデータ部分の両方をチェックします)
  • チェックサムは、まずデータ送信側で特別なアルゴリズムによって計算され、その後、受信側に送信された後に再計算されます。データグラムが送信中に第三者によって改ざんされたり、回線ノイズなどにより破損したりすると、送信側と受信側のチェックサム計算値が一致しなくなるため、UDP プロトコルではエラーの有無をチェックすることができます。
  • 送信元ポート番号: 相手が返信する際に選択します。必要ない場合はすべて0でも構いません。
  • 宛先ポート番号: 宛先でメッセージを配信するときに使用する必要があります
  • 長さ: UDP ユーザー データグラムの長さ。最小値は 8 (ヘッダーのみ)

UDP の特徴:

  • 接続なし: 相手側のIPとポート番号を受信した後、接続を確立せずにデータを直接送信します。
  • 信頼性が低い: 確認メカニズムや再送信メカニズムがなく、ネットワーク障害がないため、セグメントを相手に送信できず、UDPプロトコル層はアプリケーション層にエラー情報を返しません。
  • データグラム指向: 読み取りおよび書き込みデータの数と量を柔軟に制御できない
  • 制御オプションが少なく、データ転送時の遅延が少なく、データ転送効率が高い
  • データグラム指向
  • アプリケーション層がUDPにどれだけ長いデータを与えても、UDPはそれを分割したり結合したりせずにそのまま送信する。

例: UDP を使用して 100 バイトのデータを送信します<br /> 送信者が sendto を 1 回呼び出すと、100 バイトが送信されます。次に、受信側も 100 バイトを受信するために、対応する recvfrom を 1 回呼び出す必要があります。ループ内で recvfrom を 10 回呼び出して、そのたびに 10 バイトを送信することはできません。
UDP バッファ
UDP には送信バッファがありません。sendto を呼び出すと、データはカーネルに直接渡され、カーネルはデータをネットワーク層プロトコルに渡してその後の送信を行います。 UDP は接続指向ではないため、再送信メカニズムはなく、送信が失敗した場合に備えて送信済みのデータを保存するバッファを送信する必要がありません。
UDP には受信バッファがあります。ただし、この受信バッファでは、受信した UDP パケットの順序が送信した UDP パケットの順序と一致することを保証できません。バッファがいっぱいになると、到着した UDP データは破棄されます。
UDPソケットは読み取りと書き込みが可能で、全二重

UDP の使用に関する注意事項:
UDP プロトコル ヘッダーの最大長は 16 ビットです。つまり、UDP で送信できるデータの最大長は 64K (UDP ヘッダーを含む) です。しかし、64K は今日のインターネット環境では非常に小さい数値です。送信する必要があるデータが 64K を超える場合は、アプリケーション層で手動でパケットに分割し、複数回送信して、受信側で組み立てる必要があります。
UDP ヘッダー内のチェックサムの計算方法は少し特殊です。チェックサムを計算する際、UDP ユーザー データグラムの前に 12 バイトの疑似ヘッダーが追加されます。疑似ヘッダーは、下方向にも上方向にも送信されず、チェックサムの計算にのみ使用されます。IP データグラム ヘッダーのみをチェックする IP データグラム チェックサムとは異なり、UDP チェックサムはヘッダーとデータ部分の両方をチェックします。

疑似ヘッダー:

UDP ベースのアプリケーション層プロトコル:

  • NFS: ネットワーク ファイル システム
  • TFTP: 簡易ファイル転送プロトコル
  • DHCP: 動的ホスト構成プロトコル
  • DNS: ドメイン名解決プロトコル

信頼性の高い伝送を実現するために UDP を使用しますか?

  • TCPの信頼性メカニズムを参考にして、アプリケーション層で同様のロジックを実装する
  • データの順序を保証するためにシリアル番号を参照する
  • 相手側がデータを受信したことを確認するための確認応答を導入する
  • タイムアウト再送信を導入します。一定時間経過しても応答がない場合は、データを再送信します。

2. 各機能の使い方

1. ソケット関数の使用

1.1 関数プロトタイプ

int ソケット(int ドメイン、int タイプ、int プロトコル);
ドメイン: ドメイン AF_INET:IPV4
    AF_INET6: IPv6 の
タイプ: SOCK_STREAM タイプ
    ソックDGARM
プロトコル: プロトコル

1.2 この関数は何をするのですか?
通信ドメインにバインドされていないソケットを作成し、ソケットを操作する後続の関数呼び出しで使用できるファイル記述子を返します。

2. バインド機能の使用

2.1 関数プロトタイプ
int bind(int socket, const struct sockaddr* address, socklen_t address_len);
2.2. 機能 この機能は、以前に作成されたソケットを使用して IP アドレスとポート番号をバインドします。つまり、ソケットはネットワーク内の特定のホストとホスト内のプロセスを識別できます。

3. recvfrom関数の使用

3.1 関数プロトタイプ

ssize_t recvfrom(int socket, void* restrict buffer, size_t length, 
                 int フラグ、struct sockaddr* 制限アドレス、 
                socklen_t* アドレス長さを制限する);
​
socket: メッセージが受信されるソケット buffer: メッセージの受信に使用されるバッファ length: 受信メッセージの長さ flags: タイプ address: 送信された情報を格納するための NULL ポインタまたは sockaddr 構造体 addless_len: アドレス パラメータが指す sockaddr 構造体の長さを指定します

3.2 機能
ソケットから送信されたメッセージを受信するために使用されます。ソケットのsockaddr構造は、

4. sendto関数の使用

4.1 関数プロトタイプ
ssize_t recvfrom(int ソケット, const void* メッセージ, size_t 長さ,
int フラグ、const struct sockaddr* dest_addr、
socklen_t* 長さ);
4.2 関数<br /> この関数は、ソケットが dest_addr からメッセージを受信するために使用します。

3. 知識を広げる

1. ネットスタット

Netstat は、TCP/IP ネットワークを監視するために使用される、重要でないツールです。構文: netstat [オプション]
機能: ネットワークステータスの表示

オプション:
-a、接続されているすべてのソケットを表示
-c、ネットワークステータスを継続的にリストする
-n、ドメインネームサーバーを経由せずにIPアドレスを直接使用し、数値として表示します。
-l、監視対象サーバーのソケットを表示し、リスニング状態のソケットのみをリストします。
-p は、ソケットを使用しているプログラムの識別コードと名前 (PID/プログラム名) を表示します。
-t、TCP伝送プロトコルの接続ステータスを表示します
-u、UDPトランスポートプロトコルの接続ステータスを表示します
-v、コマンドの実行プロセスを表示する
-V、バージョン情報を表示
-x、UNIXトランスポートプロトコルの接続ステータスを表示します
-s、ネットワーク作業情報統計を表示
-h、オンラインヘルプ

2. ピドフ

サーバープロセスIDを表示するのは非常に便利です

構文: pisdof [プロセス名]

機能: プロセス名でプロセス ID を表示する

Linux で UDP を学ぶこの記事はこれで終わりです。Linux に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Linux インデックスノード inode の詳細な説明
  • Linux デバイスに空き容量がありません inode の満杯により 500 エラーが発生します
  • Linux ネットワーク設定の詳細
  • MyCat を使用して Linux で MySQL マスター/スレーブの読み取り/書き込み分離を実装する方法
  • Unix/Linuxフォークの隠れたオーバーヘッド
  • Linux スワップ パーティション (詳細説明)
  • Linux での C++ ネットワーク プログラミング、epoll テクノロジ、Windows での IOCP モデル
  • Linux サーバーは最大いくつのポートを開くことができますか?
  • Linux ファイル記述子、ファイルポインタ、および inode の詳細

<<:  MySQL 起動失敗の問題とシナリオ分析

>>:  要素の円弧モーションを実現する CSS3 サンプルコード

推薦する

CSS3 パッケージ化後にプレフィックスプラグインを自動的に追加する方法の詳細な説明: autoprefixer

vue-cli で構築されたプロジェクト スキャフォールディングでは、すでに autoprefix...

JavaScript 構造化代入の詳細な説明

目次コンセプト配列の分割値を個別に宣言して割り当てるデフォルト値の構造化解除変数値の交換関数によって...

Reactスロットの使い方

目次必要コアアイデアReactでスロットを実装する2つの方法必要コンポーネントを自分で書きました。コ...

MySQL 8.0 の非表示列に対する基本操作

目次01 非表示の列を作成する02 非表示の列に対する基本操作03 非表示の列メタデータ04 主キー...

フロントエンドJavaScript ES6の詳細について

目次1. はじめに1.1 Babel トランスコーダ1.2 ポリフィル2. let と const ...

JavaScript の useRef と useState の紹介

目次1. useStateフック2. useRefフック3. useRef と useState 4...

ARM64アーキテクチャでmysql5.7.22をインストールするプロセス全体

MySQLダウンロードアドレス: https://obs.cn-north-4.myhuaweicl...

vitrualBox+ubuntu16.04 python3.6 最新チュートリアルと詳細な手順のインストール

最近ディープラーニングを学ぶためにUbuntu+Python 3.6バージョンを使う必要があるため、...

CSS3 疑似クラスセレクターの簡単なレビュー

序文CSS がフロントエンド開発の基本的なスキルであるならば、「セレクター」は基礎中の基礎です。これ...

Nginx コンテンツ キャッシュと共通パラメータ設定の詳細

使用シナリオ:プロジェクトのページでは、頻繁に変更されず、個別のカスタマイズも伴わない大量のデータを...

nginx で Vue プロジェクトをデプロイする方法

今日は nginx サーバーを使用するのですが、vue プロジェクトをサーバーにデプロイする必要もあ...

nginx-ingress-controller ログ永続化ソリューションのソリューション

最近、nginx-ingress-controller のアプリケーションについて説明した公開アカウ...

CSS: 訪問した疑似クラスセレクタの秘密の記憶

昨日、a:visited を使用して「Guess You Like」の右側にある訪問済みテキストの色...

JavaScript parseInt() と Number() の違いのケーススタディ

学習目標: parseInt() と Number() という 2 つの関数は、文字列をデータ型に変...