TCPはコネクション型のプロトコルであり、双方は、第1の通信接続を確立する必要があります。ほとんどのアプリケーションで使用されるTCP、しかし、その比較的高いシステムリソース要件の信頼性と安定した特性ので。
開発プロセスに示されているように、以下のようにTCPプロトコルサーバー手順があります。
//は、プロトコルバージョンのためのWinsockライブラリを初期化 // サービスSocketオブジェクトを作成します(指定したプロトコルタイプ、住所、家族情報) // バインドソケット(ポートがソケットに結合し、IPを指定) // リスニングを開始し、リスナーの数を設定します。(モニタリングの開始後、クライアントが正常に接続することができます) // 接続を受信するポートを開く // 送信し、(通信の接続を確立するために、Socketオブジェクトを使用して)データを受信 // 近い接続ソケット // 呼び出し終了のWinsockライブラリー
、TCPサーバプログラムを開発完了初期のWinsockライブラリとソケット(ソケット)ターゲットを作成する二つの一般的な手順の後、私たちは、次の手順を完了する必要があります。
(1)指定されたIPアドレスとポートにソケットをバインド
どんなに使用のサーバー側のプログラムにどのプロトコル、以前に作成したソケットにそれと通信するためのクライアントプログラムをサーバーのIPアドレスとポートをバインドする必要があります。そのバインドソケット、次のプロトタイプをバインドする機能。
int型バインド( SOCKET S、// ソケットハンドルが CONST ストラクト FARのsockaddrを*名、 // アドレスバインドへ のint namelenを // アドレス長は、名前で指定されました )。
最初のパラメータsは、ソケット関数によって返されたアドレスをバインドするソケットハンドルです。
第二のパラメータはのsockaddr構造を名前へのポインタである、ソケットのアドレスがバインドされている指定するために使用されます。
TCP、UDPプロトコルの場合、アドレスは通常、TCPのためのIPアドレスとポート番号、構造の代わりのsockaddrのsockaddr_in UDPプロトコルです。これは以下に定義されます。
ストラクトのsockaddr_inを{ ショート sin_familyは; // アドレスファミリ(アドレス形式)、AF_INETなどのWindows u_short sin_portは; // ポート番号 構造体 in_addr形式sin_addr; // のIPアドレス チャー 用sin_zero [ 8 ]; // プレースホルダ値は、通常0 }。
関数パラメータAF同じソケットsin_familyは最初のメンバー。
第2部材sin_portは、TCPまたはUDP通信サービスのポート番号を指定します。アプリケーションは、IANA(インターネット割り当て番号Authorith)管理により、1023のような0をポート番号を選択する際に注意を払う必要があり、公共サービスのために予約、共通のユーザー・アプリケーションは、1024以上のポート番号を選択する必要があります。また注目すべきは、ここで使用される値は、ネットワークバイトオーダーで、その数は、コンピュータのホストバイトオーダに格納されます。以下に示すように、Winsockのライブラリーは、二つの配列の間で変換するための変換関数のセットを提供します。
htonsは(hostshort u_short)u_short; // ネットワークバイト順にホストによってバイト順変換u_shortタイプ u_longのhtonl(u_longのhostlong); // ネットワークバイト順にホストによってタイプu_longのバイト順変換 ntohs u_short(u_short netshort); // 型u_shortは、ホストバイト順にネットワークバイト順から変換 (u_longのnetlong)u_longのntohl; // u_longのホストバイトオーダーにネットワークバイト順から変換タイプ
例えば、我々はポート6000を使用したい、それはsin_portは= htons(6000)である必要があります。
第三のメンバーsin_addrは、以下に定義されるような全32ビット値にジョイント処理として定義されているIPアドレスを格納するために使用されます。
構造体in_addr形式{ 組合{ 構造体{u_char型s_b1、s_b2、s_b3、s_b4。} S_un_b。 構造体{u_short s_w1、s_w2。} S_un_w。 u_longのS_addr; } 太陽;
私たちは、各部分が通常「xxx.xxx.xxx.xxx」の形式の点、で区切って、IPアドレスは4つの部分で構成さを知っています。AN IPアドレスは、各部分の各バイトは、ドットで区切られなければならない、実際に4バイトからなる32ビットのデータ、すなわち、です。したがって、各セクションの最大値は255です。この文字列の割り当てのメンバーの直接の使用は、通常、変換する必要がある場合は、Winsockのライブラリは、以下の変換機能を提供します。
符号なしの長いのinet_addr(のconst のchar FAR * CP); チャー FAR * INET_NTOA(構造体 in_addr形式で)。
アクション機能は、ネットワークバイト順で文字列登録変更によって表される32ビットのIPアドレス値のinet_addrです。
INET_NTOAアクション機能は、ネットワークバイト順の32ビット値のIPアドレスで表されているIPアドレスの文字列表現を変換することです。
同じサイズのセットは、他の意味にsockaddr構造体sin_zero第4部材。
この関数は、それはそれ以外の場合はエラーコードを取得するにはSOCKET_ERROR、使用WSAGetLastError関数を返し、0を返します成功します。
(2)接続をリッスン
IPアドレスとポート番号を指定を結合するためのソケットがあること、リスニングステートにソケットの後に設定されるべきである場合には、クライアント接続を待ち受けます。使用次のように関数のプロトタイプがある聞きます。
int型(耳を傾け SOCKET S、 // ソケットハンドル int型のバックログ // キューに残るために許可されている接続のリッスン最大数が処理されていません
)。
リスニング状態にサーバーセットソケット、およびキューがまだ満杯でない場合は、クライアントの接続機能は、接続が成功するか、タイムアウトになったまではそうでない場合は、クライアントの接続処理機能をブロックします、正常に接続することができます。
(3)接続要求を受け付け
リスニング状態にサーバソケット、それは受け入れる機能を使用する必要がありますが、回線接続中で待機して受け入れるとの接続を完了するために、すぐに復帰するために待機している接続が存在する場合、この関数を入力するか、受け入れる接続の到着、またはソケットオブジェクトがあるまでブロックします閉じます。次のように関数のプロトタイプがある受け入れます。
SOCKET受け入れる( SOCKET Sを、// ソケットハンドルは ストラクトのsockaddr FAR * ADDR、// 構造のsockaddr_inポインタ、アドレス受信するための他 のint FAR * addrlenは // メモリサイズにADDRポインタ )。
この関数は、最初の未処理の接続部に接続されたソケットで撮影し、新しいソケットを作成し、この新しいポストを使用して、コネクタ、データの送受信にそのハンドルを返し、ソケットを完了することです。
次のように図TCPクライアントプログラムの開発プロセスです。
// プロトコルバージョンのためのWinsockライブラリの初期化 // サービスSocketオブジェクトを作成します(指定したプロトコルタイプ、住所、家族情報) // 接続(サーバーに接続するためにIPとポートを指定) // 確立された接続を使用して(データの送受信Socketオブジェクトがされると通信) // 近い接続ソケット // のWinsockの呼び出しを終了
TCPクライアントプログラムの開発の完了については初期のWinsockライブラリとソケット(ソケット)ターゲットを作成する二つの一般的な工程の後、次のステップは、サーバーへの接続機能が開始接続を使用することで次のように、関数のプロトタイプです。
int型接続(SOCKET Sは、 // ソケットハンドルが CONST ストラクト *名、FARのsockaddrを// サーバーの構造のsockaddr_inポインタ、指定されたアドレスを接続するために int型 NAMELEN // addrは、ポインタメモリサイズに )。
関数が0を返す成功し、その後、sがソケットを使用してデータを送受信することができます。機能をさらにSOCKET_ERROR、利用機能を返しWSAGetLastErrorエラーコードの取得に失敗しました。
かどうかは、TCPプロトコルサーバープログラムまたはクライアントプログラムは、データが送信機能のプロトタイプを使用して送信され、次のようです。
int send( SOCKET s, //已建立连接的套接字句柄 const char FAR *buf, //要发送的内容所在内存首地址 int len, //发送内容的长度 int flags //指定调用方式,通常置为0 );
函数执行成功后返回实际发送数据的字节数。
接收数据使用recv函数,原型如下。
int recv( SOCKET s, //已建立连接的套接字句柄 char FAR *buf, //要接收的内容所在内存首地址 int len, //接收数据缓冲区的长度 int flags //指定调用方式,通常置为0
);
函数执行成功后返回实际接收数据的字节数。在阻塞模式下,recv将阻塞线程的执行,直至接收到数据。