ネットワークソケットは、コンピュータネットワークのネットワークノード内に存在するソフトウェア構造であり、ネットワークを介したデータの送受信のエンドポイントとして機能します。ソケットの構造と特性は、ネットワークアーキテクチャのアプリケーションプログラミングインターフェース(API)によって定義されます。ソケットは、ノード上で実行されているアプリケーションのプロセスの実行期間中にのみ作成されます。
インターネットの発展に伴いTCP/IPプロトコルが標準化されたため、ネットワークソケットという用語はインターネットプロトコルスイートの文脈で最も一般的に使用され、そのためインターネットソケットとも呼ばれます。この文脈では、ソケットはトランスポートプロトコル、IPアドレス、ポート番号の3つの要素からなるソケットアドレスによって、他のホストから外部的に識別されます。
ソケットという用語は、ノード内部のプロセス間通信(IPC)のソフトウェアエンドポイントにも使用され、多くの場合、ネットワークソケットと同じAPIを使用します。
ソフトウェアにおける「ソケット」という用語は、電気ケーブルで接続されたノード間の通信を行うハードウェアデバイスである電気メス型コネクタの機能に類似しています。同様に、「ポート」という用語は、ノードまたはデバイス上の外部の物理的なエンドポイントを指します。
ネットワークプロトコルスタックのアプリケーションプログラミングインターフェース(API)は、アプリケーションによって作成された各ソケットに対してハンドルを作成します。これは一般的にソケットディスクリプタと呼ばれます。Unix系オペレーティングシステムでは、このディスクリプタはファイルディスクリプタの一種です。アプリケーションプロセスは、通信チャネル上のすべての読み書き操作で使用するために、このディスクリプタを保存します。
API で作成される際、ネットワークソケットは、通信に使用するネットワークプロトコルの種類、ホストのネットワークアドレス、およびポート番号の組み合わせにバインドされます。ポートは、ノードの別の種類のソフトウェア構造を表す番号付きリソースです。ポートはサービスタイプとして使用され、プロセスによって作成されると、外部(ネットワーク)からアクセス可能なロケーションコンポーネントとして機能し、他のホストが接続を確立できるようになります。
ネットワークソケットは、2つのノード間の通信のための永続的な接続専用に使用される場合もあれば、コネクションレス通信やマルチキャスト通信に参加するために使用される場合もある。
実際には、インターネット上で使用されているTCP/IPプロトコルの普及に伴い、「ネットワークソケット」という用語は通常、インターネットプロトコル(IP)での使用を指すようになりました。そのため、 「インターネットソケット」とも呼ばれることがよくあります。
アプリケーションは、プロトコルタイプ、IPアドレス、ポート番号の組み合わせを知ることで、TCP/IPを使用してデータを交換することにより、リモートプロセスと通信できます。この組み合わせは、ソケットアドレスと呼ばれることがよくあります。これは、ネットワークソケットへのネットワーク接続ハンドルです。リモートプロセスは、プロトコルスタックの独自のインスタンスにネットワークソケットを確立し、ネットワークAPIを使用してアプリケーションに接続し、アプリケーションが使用できるように独自のソケットアドレスを提示します。
プロトコルスタックは、通常、オペレーティングシステムによって提供される(例えば、独立したライブラリとして提供されるのではなく)一連のサービスであり、スタックが実装するプロトコルを使用してプロセスがネットワーク上で通信できるようにするものです。オペレーティングシステムは、IPおよびトランスポートプロトコルのヘッダーからソケットアドレス情報を抽出し、アプリケーションデータからヘッダーを削除することで、受信したIPパケットのペイロードを対応するアプリケーションに転送します。
プログラムがネットワークソケットを使用してプロトコルスタックと通信するために使用するアプリケーションプログラミングインターフェース(API)は、ソケットAPIと呼ばれます。このAPIを利用するアプリケーションプログラムの開発は、ソケットプログラミングまたはネットワークプログラミングと呼ばれます。インターネットソケットAPIは通常、 Berkeleyソケット標準に基づいています。Berkeleyソケット標準では、ソケットはファイルディスクリプタの一種です。これは、「すべてはファイルである」というUnixの哲学と、ソケットとファイルの類似性によるものです。どちらにも、読み取り、書き込み、オープン、クローズの機能があります。実際には、違いがあるため類似性は限定的であり、ソケットでは異なるインターフェース(送信と受信)が使用されます。プロセス間通信では、通常、各エンドが独自のソケットを持ちます。
標準的なインターネットプロトコルであるTCPとUDPでは、ソケットアドレスはIPアドレスとポート番号の組み合わせであり、電話回線の一方の端が電話番号と特定の内線番号の組み合わせであるのとよく似ています。ソケットは、例えばデータ送信のみを行う場合、送信元アドレスを持つ必要はありませんが、プログラムがソケットを送信元アドレスにバインドすると、そのアドレスに送信されたデータを受信するためにソケットを使用できます。インターネットソケットは、このアドレスに基づいて、受信したデータパケットを適切なアプリケーションプロセスに配信します。
ソケットとは、多くの場合、インターネットソケットまたはTCPソケットを指します。インターネットソケットは、少なくとも以下の特徴を備えています。
ソケット(内部表現)、ソケット記述子(抽象識別子)、ソケットアドレス(公開アドレス)の区別は微妙であり、日常的な使用では必ずしも区別されるとは限りません。さらに、ソケットの具体的な定義は著者によって異なります。IETF Request for Comments、インターネット標準、多くの教科書、そしてこの記事では、ソケットという用語は、 ソケット番号によって一意に識別されるエンティティを指します。他の教科書では、[ 1 ]ソケットという用語は、ローカルソケットアドレス、つまり「IP アドレスとポート番号の組み合わせ」を指します。RFC 147 [ 2 ]で与えられたソケットの元の定義では、 1971 年にARPA ネットワークに関連して、 「ソケットは 32 ビットの数値として指定され、偶数ソケットは受信ソケットを、奇数ソケットは送信ソケットを識別します」。しかし、今日では、ソケット通信は双方向です。
オペレーティングシステムおよびソケットを作成したアプリケーション内では、ソケットはソケット記述子と呼ばれる一意の整数値によって参照されます。
Unix系オペレーティングシステムやMicrosoft Windowsでは、確立されたソケットや関連情報を一覧表示するために、コマンドラインツールnetstatまたはss [ 3 ]が使用されます。
このJavaの例は、 Berkeleyソケットインターフェースに基づいてモデル化されており、 TCP経由でアドレスを持つホストのポートに「Hello, world!」という文字列を送信します。ソケットの作成、リモートホストへの接続、文字列の送信、そして最後にソケットを閉じるまでの手順を示しています。80203.0.113.0
パッケージorg.wikipedia.examples ;import java.io.IOException ; import java.io.PrintWriter ; import java.net.InetAddress ; import java.net.Socket ; import java.net.SocketException ;public class Main { public static void main ( String [] args ) { InetAddress address = InetAddress . getByName ( "203.0.113.0" );// IP = 203.0.113.0、ポート = 80 // try ブロックの最後にソケットが自動的に閉じられます// java.net.Socket は TCP を使用し、java.net.DatagramSocket は UDP を使用しますtry ( Socket socket = new Socket ( address , 80 )) { // 自動フラッシュを有効にして、ソケットの出力ストリームに書き込みますPrintWriter socketOut = new PrintWriter ( socket . getOutputStream (), true ); socketOut . println ( "Hello, world!" ); } catch ( SocketException e ) { System . out . printf ( "ソケットへのアクセス中にエラーが発生しました: %s%n" , e . getMessage ()); e . printStackTrace (); } catch ( IOException e ) { System . out . printf ( "ソケットへの書き込み中にエラーが発生しました: %s%n" , e . getMessage ()); e . printStackTrace (); } } }C言語における従来のBerkeleyソケットの使用方法は次のようになります。
#include <stdio.h> #include <stdlib.h> #include <string.h>#include <arpa/inet.h> #include <unistd.h>int main () { char message [] = "Hello, World!" ;// ソケットを作成するint sockfd = socket ( AF_INET , SOCK_STREAM , 0 ); if ( sockfd == -1 ) { fprintf ( stderr , "ソケットの作成に失敗しました! \n " ); return 1 ; }// サーバーアドレスを設定しますstruct sockaddr_in server_addr = { . sin_family = AF_INET , // アドレスファミリー. sin_port = htons ( 80 ), // ポート番号 (ネットワークバイトオーダーに変換) . sin_addr . s_addr = inet_addr ( "203.0.113.0" ), // IP アドレス};// サーバーに接続if ( connect ( sockfd , ( struct sockaddr * ) & server_addr , sizeof ( server_addr )) == -1 ) { fprintf ( stderr , "接続に失敗しました! \n " ); return 1 ; }// メッセージを送信send ( sockfd , message , strlen ( message ), 0 ); printf ( "メッセージが送信されました! \n " );// ソケットを閉じるclose ( sockfd ); return 0 ; }インターネットソケットにはいくつかの種類があります。
他のソケットタイプは、システムネットワークアーキテクチャ[ 10 ]や内部プロセス間通信用のUnixドメインソケットなどの他のトランスポートプロトコル上で実装されています。
アプリケーションサービスを提供するコンピュータプロセスはサーバーと呼ばれ、起動時に待機状態のソケットを作成します。これらのソケットは、クライアントプログラムからの応答を待機しています。
TCPサーバーは、各クライアント接続ごとに新しい子プロセスまたは処理スレッドで固有の専用ソケットを作成することにより、複数のクライアントに同時にサービスを提供できます。これらのソケットは、リモートソケットとの間でソケット間仮想接続または仮想回線(VC)、別名TCPセッションが確立され、双方向バイトストリームが提供されるときに確立状態になります。
サーバーは、同じローカルポート番号とローカルIPアドレスを持つ複数のTCPソケットを同時に作成できます。各ソケットは、それぞれ独自のサーバー子プロセスにマッピングされ、独自のクライアントプロセスにサービスを提供します。リモートソケットアドレス(クライアントIPアドレスまたはポート番号)が異なるため、つまりソケットペアのタプルが異なるため、オペレーティングシステムはこれらを異なるソケットとして扱います。
UDPソケットには確立された状態がありません。これは、UDPプロトコルがコネクションレスであるためです。UDPサーバープロセスは、同じソケットを介して、すべてのリモートクライアントからの受信データグラムを順番に処理します。UDPソケットはリモートアドレスではなく、ローカルアドレスのみで識別されますが、各メッセージには関連付けられたリモートアドレスがあり、ネットワークアプリケーションプログラミングインターフェイス(API)を使用して各データグラムから取得できます。
TCP を介して通信するローカルソケットとリモートソケットは、ソケットペアと呼ばれます。各ソケットペアは、送信元および宛先 IP アドレスとポート番号、つまりローカルソケットアドレスとリモートソケットアドレスからなる一意の4 タプルで記述されます。 [ 11 ] [ 12 ]上記のように、TCP の場合、ソケットペアは接続の両端で一意の 4 タプルに関連付けられます。
ソケットという用語は、1971年にRFC 147が公開された際にARPANETで使用されたことに由来します。ソケットの最新の実装のほとんどは、 Berkeleyソケット(1983年)やWinsock (1991年)などの他のスタックに基づいています。Berkeley Software Distribution (BSD)のBerkeleyソケットAPIは、4.2BSD UnixオペレーティングシステムのAPIとして始まりました。しかし、UC BerkeleyがAT&Tの著作権で保護されたUnixのライセンス制約から解放されたバージョンのオペレーティングシステムとネットワークライブラリをリリースできたのは1989年になってからのことでした。
1987年頃、AT&TはUNIX System V Release 3 (SVR3)でSTREAMSベースのトランスポート層インターフェース(TLI)を導入し[ 13 ]、Release 4 (SVR4)にも引き継いだ[ 14 ] 。
その他の初期の実装は、TOPS-20 [ 15 ] MVS [ 15 ] VM [ 15 ] IBM -DOS (PCIP) [ 15 ] [ 16 ]向けに作成されました。
ソケットは主に、インターネットプロトコルスイートのトランスポート層、またはOSIモデルのセッション層で使用される概念です。インターネット層で動作するルータや、リンク層で動作するスイッチなどのネットワーク機器は、トランスポート層の実装を必要としません。ただし、ステートフルネットワークファイアウォール、ネットワークアドレス変換器、プロキシサーバは、アクティブなソケットペアを追跡します。マルチレイヤースイッチやルータのQoS(サービス品質)サポートでは、ソケットペアに関する情報を抽出することでパケットフローを識別できます。
生ソケットは通常、ネットワーク機器に搭載されており、 IGRPやOSPFなどのルーティングプロトコル、およびインターネット制御メッセージプロトコル(ICMP)に使用されます。