C言語-ソケットプログラミング_TCPソケット

TCP (Transmission Control Protocol)ソケットについて

Transmission Controlとは

transmissionとは伝送、送信という意味であり、それをcontrol(制御)するという意味です。

接続相手、再送制御、データ到着の確認、データの保証対応(重複や抜け)の検出などを行う機能を指します。


TCPの特徴

TCPはコネクション型(通信相手と接続を確立し、データ伝送が完了すると切断する)プロトコルです。

データが確実に通信相手に送信されたことを保証する、データの欠落や破損を検知して再送する、届いたデータを送信順に並べ直すというような制御が行われます。

信頼性は高いが転送効率は低く、通信経路の品質によっては遅延が生じたり通信不能になりやすい問題があります。


TCPソケットのクライアント処理

1,socket()を実行してTCPソケットを作成する。

ソケットタイプを「SOCK_STREAM」にして、プロトコルを「IPPROTO_TCP」にします。


socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

2,connect()を実行してサーバへの接続を確立する。

ローカルソケットとリモートソケットの間にコネクションを確立します。

正常終了すると、ローカルソケットには以下の情報が割り当てられます。

  • ローカルIPアドレス
  • リモートIPアドレス
  • ローカルポート
  • リモートポート

connect(sd, (struct sockaddr *)sv_addr, sizeof(sv_addr));

struct sockaddr_inをstruct sockaddrでキャストする必要があります。


3,send()/recv()などで通信を行う。

ソケットディスクリプタを用いてデータの送受信処理を行います。


int send( int socket, const void *msg, unsigned int msgLength, int flag );
int recv( int socket, void *msg, unsigned int msgLength, int flag );

4,close()で通信を終了する。

ソケットでの通信を終了します。

正常終了すると、そのソケットでは以後送受信できないというマーキングがされます。

送信のみ終了させるなど制御が必要な場合にはshutdown()関数を利用します。


TCPソケットのサーバ処理

1, socket()を実行してTCPソケットを作成する。

ソケットタイプを「SOCK_STREAM」にして、プロトコルを「IPPROTO_TCP」にします。


socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

2, bind()を実行してソケットにポート番号を割り当てる

ローカルアドレスとローカルポートをソケットに割り当てます。


bind(sock, (struct sockaddr *)&sv_addr, sizeof(struct sockaddr));

3, listen()を実行してポート番号への接続を作成できることをシステムに伝える。

ソケットを接続待ち状態(リッスン中)にします。

コネクションの確立時にクライアントからの接続要求を格納するキューをサーバ側で作ります。

指定ソケットの内部状態が変更され、着信するTCP接続要求を処理します。


#include<sys/socket.h>
int listen(int socket, int queue_limit);

queue_limitには5を指定することが一般的です。

ただし、queue_limitはシステムによって意味が異なることがありますので、システムの技術仕様を確認する必要があります。


4, クライアントからの接続要求に対して、accept()を呼び出して新しいソケットを取得する。

コネクションの確立時に、該当するソケットへの接続を待つ動作を用意します。

クライアントからの接続要求に合わせて、listen()でキューイングしたソケットを取り出します。


#include<sys/socket.h>
int accept(int socket, struct sockaddr *address, size_t *address_len);

第3引数はポインタ渡しとなるので注意が必要です。


5, ソケットを介してクライアントと通信を行う。

accept()で取得したソケットディスクリプタを用いてデータの送受信処理を行います。

send()及びrecv()を用います。

もしくは、ファイルディスクリプタ操作で標準的に利用されるread()関数とwrite()関数を用いることも可能です。


6, close()を実行してクライアントとの接続を終了する。

そのソケットでの通信を終了します。


関連ページ


UDP通信


TCP通信