TCP-echoクライアント Python socket module: Just a thin wrapper over the underlying C library's socket calls. TCP-echoクライアント TCP-echoクライアントのプログラムモデル(Cプログラム) クライアントのソケットオブジェクト ソケットオブジェクトの作成と削除(Cプログラム) サーバへの接続とアドレスの指定(Cプログラム) TCP-echoクライアントCプログラム(サーバへ接続するソケットを作成 ) TCP-echoクライアントCプログラム(サーバへの接続、メッセージ送信 ) TCP-echoクライアントCプログラム(サーバからの返信メッセージの受信 ) TCP-echoクライアントPythonプログラム TCP-echoクライアント ソケットによるデータ通信とTCP/IPネットワーク IPヘッダ情報 IP TCP TCPヘッダ情報 データ データ TCP/IP ネットワーク •通信プログラムを作成する上では、通信相手のソケットに自分の ソケットを繋ぐことができれば、安定した通信を行うことができる。 •安定した通信は、TCP/IPのプロトコルで自動的に対処される。 •ソケットを繋ぐことができれば、 マシン同士が、どの様な通信機器 や伝送経路を辿って、データを送受信しているかなどを気にする必 要は無くなる。 TCP-echoクライアント TCP-echoクライアントのプログラムモデル (Cプログラム) 1. socket()を実行 (ソケット作成) ↓ 2. connect()を実行 (サーバ接続) ↓ 3. send()とrecv()を実行 (データ通信を行う) ↓ 送信メッセージの ソケット識別子 アドレス int send(int socket, const void *msg, unsigned int msgLength, int flags) TCPEchoClient TCPEchoServer socket() bind() listen() socket() connect() コネクション設定 データ データ send() ”Hello” IP TCP ”Hello” 戻値は送信バイト数 0はデフォルトの振舞 recv() ソケット識別子 戻値は受信バイト数 0はデフォルトの振舞 ↓ 4. close()を実行 (ソケット削除) recv() ”Hello” ”Hello” 送信バッファ のアドレス int recv(int socket, void *revBuffer, unsigned int bufferLength, int flags) accept() send() コネクション開放 close() close() TCP-echoクライアント クライアントのソケットオブジェクト データ データ AP AP データ AP AP ソケット ソケット 1 2 65535 1 2 IP AP AP ソケット ソケット 1 2 65535 TCP UDP データ 65535 1 2 TCP UDP IP TCP 65535 IP TCP-echoクライアント ソケットオブジェクトの作成と削除 (Cプログラム) SOCK_STREAM (TCPの場合) SOCK_DGRAM (UDPの場合) PF_INET (TCP/IPの場合) ソケット作成 int socket(int protocolFamily, int type, int protocol) 戻値: 成功:ソケット識別子、 失敗:-1 IPPROTO_TCP (TCPの場合) ソケット削除 IPPROTO_UDP (UDPの場合) 0 (デフォルト) ソケット識別子 int close(int socket) データ データ AP AP AP ソケット ソケット IP 1 65535 TCP 1 2 2 65535 TCP UDP IP TCP-echoクライアント サーバのアドレスの指定と接続 (Cプログラム) ソケット識別子 サーバ接続 サーバのIPアドレスとポート番号 int connect(int socket, struct sockaddr *foreinAddress, unsigned int addressLength) os、ネットワークの違いを吸収 sa_data sa_family ビットの並び(14バイト) ファミリ 2バイト sin_family 2バイト sin_port 4バイト sin_addr 8バイト sin_zero ファミリ ポート IPアドレス AF_INET (TCP/IPの場合) ポート番号 struct sockaddr { unsigned short sa_family; char sa_data[14]; }; 未使用 IPアドレス struct sockaddr_in { unsigned short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; TCP-echoクライアント TCP-echoクライアントCプログラム (サーバへ接続するソケットを作成 ) void DieWithError(char *errorMessage); /* エラー処理 */ TCPEchoClient.c TCPEchoClient int main(int argc, char *argv[]) { int sock; // ソケット識別子 struct sockaddr_in echoServAddr; // エコーサーバのIPアドレス socket() char *servIP; //サーバのIPアドレス(10進表記) char *echoString; //エコー文字列 connect() unsigned short echoServPort; //エコーサーバのポート番号 データ char echoBuffer[RCVBUFSIZE]; //エコー文字列受信時のバッファ unsigned int echoStringLen; //エコー文字列の長さ send() int bytesRcvd, totalBytesRcvd; // 1回のrecv()で読むバイト数 と全バイト数 ”Hello” servIP = argv[1]; // 引数1は、サーバのIPアドレス echoString = argv[2]; //引数2は、エコー文字列 echoServPort = atoi(argv[3]); /* 引数3はローカルポート番号 */ ソケット作成 // ストリームソケットを使う if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("socket() failed"); recv() DieWithError.c TCPEchoServer socket() bind() listen() コネクション設定 accept() データ ”Hello” IP TCP recv() ”Hello” ”Hello” send() コネクション開放 close() close() TCP-echoクライアント TCP-echoクライアントCプログラム (サーバへの接続、メッセージ送信 ) // サーバアドレス構造体を作成 // 構造体に0を埋める memset(&echoServAddr, 0, sizeof(echoServAddr)); // インタネットアドレスファミリ echoServAddr.sin_family = AF_INET; // サーバのIPアドレス echoServAddr.sin_addr.s_addr = inet_addr(servIP); // サーバのポート番号 echoServAddr.sin_port = htons(echoServPort); TCPEchoClient TCPEchoServer socket() bind() listen() socket() connect() コネクション設定 データ サーバ接続 // エコーサーバに接続 if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0) DieWithError("connect() failed"); // エコー文字列の長さを求める echoStringLen = strlen(echoString); 送信 // エコー文字列tを送信 if (send(sock, echoString, echoStringLen, 0) != echoStringLen) DieWithError("send() sent a different number of bytes than expected"); accept() データ send() ”Hello” IP TCP ”Hello” recv() recv() ”Hello” ”Hello” send() コネクション開放 close() close() TCP-echoクライアント TCP-echoクライアントCプログラム (サーバからの返信メッセージの受信 ) // エコー文字列をサーバから受信 TCPEchoClient TCPEchoServer totalBytesRcvd = 0; 受信 printf("Received: "); socket() // バッファサイズまで、エコー文字列を受信 bind() while (totalBytesRcvd < echoStringLen) listen() { socket() if ((bytesRcvd = recv(sock, echoBuffer, コネクション設定 accept() RCVBUFSIZE - 1, 0)) <= 0) connect() DieWithError("recv() failed or connection closed データ データ prematurely"); // 総受信バイト数を求める ”Hello” IP send() recv() totalBytesRcvd += bytesRcvd; TCP // 文字列の終了(NULL)を追加 ”Hello” ”Hello” echoBuffer[bytesRcvd] = '\0'; ”Hello” recv() // エコーバッファの内容を表示 send() printf(echoBuffer); } コネクション開放 // ラインフィード close() close() printf("\n"); ソケット削除 // ソケットのクローズ close(sock); exit(0); } TCP-echoクライアント TCP-echoクライアントPythonプログラム import sys from socket import * TCPEchoClient.py TCPEchoClient TCPEchoServer server_host = "localhost" server_port = 50007 def test(): global server_host message = ["Hello network world"] if len(sys.argv) > 1: server_host = sys.argv[1] if len(sys.argv) > 2: message = sys.argv[2:] sock_obj = socket(AF_INET, SOCK_STREAM) sock_obj.connect((server_host, server_port)) for line in message: sock_obj.send(line) data = sock_obj.recv(1024) print "Client received data : ", str(data) sock_obj.close() if __name__ == '__main__': print "TCPEchoClient", server_host, server_port test() socket() bind() listen() socket() connect() コネクション設定 データ accept() データ send() ”Hello” IP TCP ”Hello” recv() recv() ”Hello” ”Hello” send() コネクション開放 close() close()
© Copyright 2024 ExpyDoc