ネットワークプログラミング講座

Download Report

Transcript ネットワークプログラミング講座

UDP-echoクライアント
Python socket module: Just a thin wrapper over the underlying C library's socket calls.
UDPエコークライアント





UDP-echoクライアントのプログラムモデル(Cプログラム)
ソケットオブジェクトの作成と削除(Cプログラム)
UDP-echoクライアントCプログラム(サーバへ接続するソケットを作成 )
UDP-echoクライアントCプログラム(メッセージ送受信 )
UDP-echoクライアントPythonプログラム
UDP-echoクライアント
UDP-echoクライアントのプログラムモデル
(Cプログラム)
1. socket()を実行 (ソケット作成)
↓
2. sendto()とrecvfrom()を実行(データ通信を行う)
int sendto(int socket, const void *msg, unsigned
int msgLength, int flags, struct sockaddr
*destAddr, unsigned int addrLen)
int recvfrom(int socket, const void *msg,
unsigned int msgLength, int flags, struct
sockaddr *srcAddr, unsigned int *addrLen)
↓
3. close()を実行 (ソケット削除)
UDPEchoClient
socket()
sendto()
recvfrom()
UDPEchoServer
ソケットリンク
接続
socket()
bind()
Echo
Echo
ソケットリンク
開放
close()
recvfrom()
sendto()
close()
UDP-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
ソケッ
ト
ソケッ
ト
1 2
655351 2
TCP
UDP
IP
65535
UDP-echoクライアントCプログラム
(サーバへ接続するソケットを作成 )
#define ECHOMAX 255 /* エコー文字列の最大長 */
int main(int argc, char *argv[])
{
int sock;
/* ソケット識別子 */
struct sockaddr_in echoServAddr; /* エコーサーバアドレス */
struct sockaddr_in fromAddr; /* エコー送信元アドレス */
unsigned short echoServPort; /* エコーサーバのポート番号 */
unsigned int fromSize; /* recvfrom()のアドレスの入出力サイズ*/
char *servIP;
/* サーバのIPアドレス */
char *echoString;
/* エコーサーバへ送信する文字列 */
char echoBuffer[ECHOMAX+1]; /* エコー文字列の受信用バッファ */
int echoStringLen;
/* エコー文字列の長さ */
int respStringLen;
/* 受信した応答の長さ */
servIP = argv[1];
/* 1つ目の引数: サーバのIPアドレス */
echoString = argv[2];
/* 2つ目の引数: エコー文字列 */
/* 入力文字列の長さをチェック */
if ((echoStringLen = strlen(echoString)) > ECHOMAX)
DieWithError("Echo word too long");
if (argc == 4) echoServPort = atoi(argv[3]); /* ポート番号指定があれば使用 */
else
echoServPort = 7; /* 7 はエコーサビスのwell-knownポート番号*/
/* UDPデータグラムソケットの作成 */
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* サーバのアドレス構造体の作成 */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* 0を埋める */
echoServAddr.sin_family = AF_INET; /* インタネットアドレスファミリ */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* IPアドレス */
echoServAddr.sin_port = htons(echoServPort);
/* ポート番号 */
UDP-echoクライアント
UDPEchoClient.c
DieWithError.c
UDPEchoClient
socket()
sendto()
recvfrom()
close()
UDPEchoServer
ソケットリンク
接続
socket()
bind()
Echo
Echo
recvfrom()
sendto()
ソケットリンク
開放
close()
UDP-echoクライアントCプログラム
UDP-echoクライアント
(メッセージ送受信 )
ソケット作成後直に
送信可能
/* 文字列をサーバへ送信 */
if (sendto(sock, echoString, echoStringLen, 0, (struct sockaddr *)
&echoServAddr, sizeof(echoServAddr)) != echoStringLen)
DieWithError("sendto() sent a different number of bytes than
expected");
想定外のコンピュータから
のメッセージがあり得る!!
/* 応答を受信 */
fromSize = sizeof(fromAddr);
if ((respStringLen = recvfrom(sock, echoBuffer, ECHOMAX, 0,
(struct sockaddr *) &fromAddr, &fromSize)) != echoStringLen)
DieWithError("recvfrom() failed");
if (echoServAddr.sin_addr.s_addr != fromAddr.sin_addr.s_addr)
{
fprintf(stderr,"Error: received a packet from unknown source.\n");
exit(1);
}
/* 受信データをNULL文字で終端させる */
echoBuffer[respStringLen] = '\0';
/* 引数のエコー文字列を表示 */
printf(“Received: %s\n”, echoBuffer);
close(sock);
exit(0);
}
UDPEchoClient
socket()
sendto()
recvfrom()
close()
UDPEchoServer
ソケットリンク
接続
socket()
bind()
Echo
Echo
recvfrom()
sendto()
ソケットリンク
開放
close()
UDP-echoクライアント
UDP-echoクライアントPythonプログラム
import sys
from socket import *
UDPEchoClient.py
UDPEchoClient
server_host = "localhost"
server_port = 50007
recv_port = server_port + 1
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_DGRAM, 0)
sock_obj.bind((server_host, recv_port))
for line in message:
sock_obj.sendto(line, (server_host, server_port))
data, address = sock_obj.recvfrom(1024)
print "Client received data : ", str(data)
sock_obj.close()
if __name__ == '__main__':
print "UDPEchoClient", server_host, server_port
test()
socket()
sendto()
recvfrom()
close()
UDPEchoServer
ソケットリンク
接続
socket()
bind()
Echo
Echo
recvfrom()
sendto()
ソケットリンク
開放
close()