Unix-sockets-socket-core-functions
Unixソケット-コア関数
この章では、完全なTCPクライアントおよびサーバーを作成するために必要なコアソケット機能について説明します。
次の図は、クライアントとサーバーの完全な相互作用を示しています-
ソケット機能
ネットワークI/Oを実行するために、プロセスが最初に行う必要があるのは、ソケット関数を呼び出すことです。目的の通信プロトコルのタイプとプロトコルファミリなどを指定します。
#include <sys/types.h>
#include <sys/socket.h>
int socket (int family, int type, int protocol);
この呼び出しは、後のシステムコールで使用できるソケット記述子を返します。エラーの場合は-1を返します。
パラメーター
ファミリ-プロトコルファミリを指定し、以下に示す定数の1つです-
Family | Description |
---|---|
AF_INET | IPv4 protocols |
AF_INET6 | IPv6 protocols |
AF_LOCAL | Unix domain protocols |
AF_ROUTE | Routing Sockets |
AF_KEY | Ket socket |
この章では、IPv4以外のプロトコルについては説明しません。
*type* -必要なソケットの種類を指定します。 それは次の値のいずれかを取ることができます-
Type | Description |
---|---|
SOCK_STREAM | Stream socket |
SOCK_DGRAM | Datagram socket |
SOCK_SEQPACKET | Sequenced packet socket |
SOCK_RAW | Raw socket |
*protocol* -引数は、以下に示す特定のプロトコルタイプに設定する必要があります。0を指定すると、ファミリとタイプの特定の組み合わせに対してシステムのデフォルトが選択されます-
Protocol | Description |
---|---|
IPPROTO_TCP | TCP transport protocol |
IPPROTO_UDP | UDP transport protocol |
IPPROTO_SCTP | SCTP transport protocol |
_connect_関数
_connect_関数は、TCPクライアントがTCPサーバーとの接続を確立するために使用します。
#include <sys/types.h>
#include <sys/socket.h>
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
この呼び出しは、サーバーへの接続に成功した場合は0を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- serv_addr -宛先IPアドレスとポートを含むsockaddr構造体へのポインタです。
- addrlen -sizeof(struct sockaddr)に設定します。
_bind_関数
_bind_関数は、ローカルプロトコルアドレスをソケットに割り当てます。 インターネットプロトコルでは、プロトコルアドレスは32ビットIPv4アドレスまたは128ビットIPv6アドレスのいずれかと、16ビットTCPまたはUDPポート番号の組み合わせです。 この関数は、TCPサーバーによってのみ呼び出されます。
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, struct sockaddr *my_addr,int addrlen);
この呼び出しは、アドレスへのバインドに成功した場合は0を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- my_addr -ローカルIPアドレスとポートを含むsockaddr構造体へのポインタです。
- addrlen -sizeof(struct sockaddr)に設定します。
IPアドレスとポートを自動的に配置できます
ポート番号の値0は、システムがランダムなポートを選択することを意味し、IPアドレスの_INADDR_ANY_値は、サーバーのIPアドレスが自動的に割り当てられることを意味します。
server.sin_port = 0;
server.sin_addr.s_addr = INADDR_ANY;
注-1024未満のすべてのポートは予約されています。 他のプログラムで使用されているポートでない限り、1024以上65535以下のポートを設定できます。
_listen_関数
_listen_関数はTCPサーバーによってのみ呼び出され、2つのアクションを実行します-
- listen関数は、接続されていないソケットを受動ソケットに変換し、カーネルがこのソケットに向けられた着信接続要求を受け入れる必要があることを示します。
- この関数の2番目の引数は、カーネルがこのソケットのためにキューに入れる必要がある接続の最大数を指定します。
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd,int backlog);
この呼び出しは成功時に0を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- backlog -許可された接続の数です。
_accept_関数
_accept_関数は、TCPサーバーによって呼び出され、完了した接続キューの先頭から次に完了した接続を返します。 呼び出しの署名は次のとおりです-
#include <sys/types.h>
#include <sys/socket.h>
int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);
この呼び出しは、成功した場合に負でない記述子を返します。そうでない場合は、エラー時に-1を返します。 返された記述子はクライアントソケット記述子であると想定され、クライアントと通信するためにこの記述子ですべての読み取り/書き込み操作が行われます。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- cliaddr -クライアントIPアドレスとポートを含むsockaddr構造体へのポインタです。
- addrlen -sizeof(struct sockaddr)に設定します。
_send_関数
_send_関数は、ストリームソケットまたはCONNECTEDデータグラムソケットを介してデータを送信するために使用されます。 UNCONNECTEDデータグラムソケットを介してデータを送信する場合は、sendto()関数を使用する必要があります。
_write()_システムコールを使用してデータを送信できます。 その署名は次のとおりです-
int send(int sockfd, const void *msg, int len, int flags);
この呼び出しは、送信されたバイト数を返します。それ以外の場合、エラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- msg -送信するデータへのポインタです。
- len -送信するデータの長さ(バイト単位)です。
- flags -0に設定されます。
_recv_関数
_recv_関数は、ストリームソケットまたはCONNECTEDデータグラムソケットを介してデータを受信するために使用されます。 UNCONNECTEDデータグラムソケットを介してデータを受信する場合は、recvfrom()を使用する必要があります。
_read()_システムコールを使用してデータを読み取ることができます。 この呼び出しは、ヘルパー関数の章で説明されています。
int recv(int sockfd, void *buf, int len, unsigned int flags);
この呼び出しは、バッファに読み込まれたバイト数を返します。そうでない場合、エラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- buf -情報を読み込むバッファです。
- len -バッファの最大長です。
- flags -0に設定されます。
_sendto_関数
_sendto_関数は、UNCONNECTEDデータグラムソケットを介してデータを送信するために使用されます。 その署名は次のとおりです-
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
この呼び出しは送信されたバイト数を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- msg -送信するデータへのポインタです。
- len -送信するデータの長さ(バイト単位)です。
- flags -0に設定されます。
- to -データを送信する必要のあるホストのsockaddr構造体へのポインタです。
- tolen -sizeof(struct sockaddr)に設定されます。
_recvfrom_関数
_recvfrom_関数は、UNCONNECTEDデータグラムソケットからデータを受信するために使用されます。
int recvfrom(int sockfd, void *buf, int len, unsigned int flags struct sockaddr *from, int *fromlen);
この呼び出しは、バッファに読み込まれたバイト数を返します。それ以外の場合は、エラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- buf -情報を読み込むバッファです。
- len -バッファの最大長です。
- flags -0に設定されます。
- from -データの読み取りが必要なホストのsockaddr構造体へのポインタです。
- fromlen -sizeof(struct sockaddr)に設定されます。
_close_関数
_close_関数は、クライアントとサーバー間の通信を閉じるために使用されます。 その構文は次のとおりです-
int close( int sockfd );
この呼び出しは成功時に0を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
_shutdown_関数
_shutdown_関数は、クライアントとサーバー間の通信を正常に閉じるために使用されます。 この関数は、_close_関数と比較してより多くの制御を提供します。 以下に示すのは、_shutdown_の構文です-
int shutdown(int sockfd, int how);
この呼び出しは成功時に0を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- sockfd -これは、ソケット関数によって返されるソケット記述子です。
- 方法-数字の1つを入れてください-
- 0 -受信が許可されていないことを示します。
- 1 -送信が許可されていないことを示し、
- 2 -送信と受信の両方が許可されていないことを示します。 _how_が2に設定されている場合、close()と同じことです。
_select_関数
_select_関数は、指定されたファイル記述子のどれが読み取りの準備ができているか、書き込みの準備ができているか、またはエラー状態が保留になっていることを示します。
アプリケーションが_recvまたはrecvfrom_を呼び出すと、そのソケットのデータが到着するまでブロックされます。 着信データストリームが空のときに、アプリケーションが他の有用な処理を実行している可能性があります。 別の状況は、アプリケーションが複数のソケットからデータを受信する場合です。
入力キューにデータがないソケットで_recvまたはrecvfrom_を呼び出すと、他のソケットからのデータの即時受信を防ぎます。 select関数呼び出しは、プログラムがすべてのソケットハンドルをポーリングして、それらが非ブロッキング読み取りおよび書き込み操作に使用できるかどうかを確認できるようにすることで、この問題を解決します。
以下に、_select_の構文を示します-
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);
この呼び出しは成功時に0を返し、そうでない場合はエラー時に-1を返します。
パラメーター
- nfds -テストするファイル記述子の範囲を指定します。 select()関数は、0からnfds-1の範囲のファイル記述子をテストします
- readfds -入力で、読み取りの準備ができているかどうかを確認するファイル記述子を指定し、出力で、読み取りの準備ができているファイル記述子を示す_fd_set_型のオブジェクトを指します。 空のセットを示すためにNULLにすることができます。
- writefds -タイプ_fd_set_のオブジェクトを指し、入力時に書き込みの準備ができているかどうかを確認するファイル記述子を指定し、出力時に書き込みの準備ができているファイル記述子を示します。 空のセットを示すためにNULLにすることができます。
- exceptfds -タイプ_fd_set_のオブジェクトを指し、入力時に、保留中のエラー状態をチェックするファイル記述子を指定し、出力時に、どのファイル記述子に保留中のエラー条件があるかを示します。 空のセットを示すためにNULLにすることができます。
- timeout -selectcallが利用可能なI/O操作の記述子をポーリングする時間を指定するtimeval構造体を指します。 タイムアウト値が0の場合、selectはすぐに戻ります。 タイムアウト引数がNULLの場合、selectは、少なくとも1つのファイル/ソケットハンドルが使用可能なI/O操作の準備ができるまでブロックします。 それ以外の場合、_select_は、タイムアウトの時間が経過した後、または少なくとも1つのファイル/ソケット記述子がI/O操作の準備ができたときに戻ります。
selectからの戻り値は、I/Oの準備ができているファイル記述子セットで指定されたハンドルの数です。 タイムアウトフィールドで指定された制限時間に達した場合、0を選択します。 ファイル記述子セットを操作するための次のマクロが存在します-
- * FD_CLR(fd、&fdset)*-ファイル記述子セット_fdset._内のファイル記述子fdのビットをクリアします
- * FD_ISSET(fd、&fdset)*-_fdset_が指すファイル記述子セットにファイル記述子_fd_のビットが設定されている場合はゼロ以外の値を返し、そうでない場合は0を返します。
- * FD_SET(fd、&fdset)*-ファイル記述子セットfdsetのファイル記述子fdのビットを設定します。
- * FD_ZERO(&fdset)*-ファイル記述子セットfdsetを初期化して、すべてのファイル記述子のビットをゼロにします。
fd引数が0より小さいか、FD_SETSIZE以上の場合、これらのマクロの動作は未定義です。
例
fd_set fds;
struct timeval tv;
/* do socket initialization etc.
tv.tv_sec = 1;
tv.tv_usec = 500000;
/*tv now represents 1.5 seconds*/
FD_ZERO(&fds);
/*adds sock to the file descriptor set*/
FD_SET(sock, &fds);
/*wait 1.5 seconds for any data to be read from any single socket*/
select(sock+1, &fds, NULL, NULL, &tv);
if (FD_ISSET(sock, &fds)) {
recvfrom(s, buffer, buffer_len, 0, &sa, &sa_len);
/*do something*/
}
else {
/*do something else*/
}