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

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. bind() (ソケットにポート番号を割当る)
↓
3. recvfrom()とsendto()を実行(データ通信を行う)
UDPEchoClient
socket()
int recvfrom(int socket, const void *msg,
unsigned int msgLength, int flags, struct
sockaddr *srcAddr, unsigned int *addrLen)
sendto()
int sendto(int socket, const void *msg, unsigned
int msgLength, int flags, struct sockaddr
*destAddr, unsigned int addrLen)
↓
4. close()を実行 (ソケット削除)
recvfrom()
UDPEchoServer
ソケットリンク
接続
socket()
bind()
Echo
Echo
ソケットリンク
開放
close()
recvfrom()
sendto()
close()
UDP-echoサーバ
サーバで利用するソケット関数
(Cプログラム)

ソケットにポート番号を割当る


サーバのアドレス
int bind(int socket, struct sockaddr *localAddress, unsigned int addressLength)
戻値:成功: 0、失敗: -1
サーバ
プログラム
sendto()
recvfrom()
サーバのソケット
bind
ソケットにポート番号
を割当る
UDP
クライアント1
クライアント2
UDP-echoサーバ
UDP-echoサーバCプログラム
(ソケットによる単純接続のリンクを作成 )
#define ECHOMAX 255 /*エコー文字列の最大長 */
int main(int argc, char *argv[])
{
int sock;
/*ソケット識別子 */
struct sockaddr_in echoServAddr; /* ローカルアドレス */
struct sockaddr_in echoClntAddr; /* クライアントアドレス */
unsigned int cliAddrLen;
/* 着信メッセージ長 */
char echoBuffer[ECHOMAX];
/* エコー文字列用バッファ */
unsigned short echoServPort; /* サーバのポート番号 */
int recvMsgSize;
/* 受信メッセージ長 */
UDPEchoServer.c
DieWithError.c
UDPEchoClient UDPEchoServer
socket()
echoServPort = atoi(argv[1]); /* 1つ目の引数: ローカルアドレス */
/* データグラムの送受信に使うソケットを作成 */
sendto()
if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
DieWithError("socket() failed");
/* ローカルのアドレス構造体を作成 */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* 0を埋める */
recvfrom()
echoServAddr.sin_family = AF_INET; /* インタネットアドレスファミリ */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* ワイルドカード */
echoServAddr.sin_port = htons(echoServPort); /* ローカルポート */
/* ローカルアドレスへバインド */
if (bind(sock, (struct sockaddr *) &echoServAddr,sizeof(echoServAddr))
< 0)
close()
DieWithError("bind() failed");
bindでソケットにローカル
アドレスを設定後、直に受
信出来る(listen()不要)
ソケットリンク
接続
socket()
bind()
Echo
Echo
recvfrom()
sendto()
ソケットリンク
開放
close()
UDP-echoサーバ
UDP-echoサーバCプログラム
(クライアントからのメッセージの受信と返信)
クライアント毎にaccept()を実行し
て、ソケットを作る必要がない
UDPEchoClient UDPEchoServer
for (;;) /* 繰返し実行 */
{
/* 入出力パラメータのサイズをセット */
cliAddrLen = sizeof(echoClntAddr);
/* クライアントからのメッセージ待ち */
if ((recvMsgSize = recvfrom(sock, echoBuffer, ECHOMAX,
0,(struct sockaddr *) &echoClntAddr, &cliAddrLen)) < 0)
DieWithError("recvfrom() failed");
printf("Handling client %s\n",
inet_ntoa(echoClntAddr.sin_addr));
socket()
sendto()
/* 受信したデータグラムをクライアントに返信 */
if (sendto(sock, echoBuffer, recvMsgSize, 0,(struct sockaddr
*) &echoClntAddr, sizeof(echoClntAddr)) != recvMsgSize)
DieWithError("sendto() sent a different number of bytes
than expected");
1ソケットから複数の
}
recvfrom()
IPアドレスへ送信
/* ここには到達しない */
}
close()
ソケットリンク
接続
socket()
bind()
Echo
Echo
recvfrom()
sendto()
ソケットリンク
開放
close()
UDP-echoサーバ
UDP-echoサーバPythonプログラム
UDPEchoServer.py
from socket import *
UDPEchoClient
my_host = ""
recv_port = 50007
send_port = recv_port +1
def test():
socket()
sock_obj = socket(AF_INET, SOCK_DGRAM, 0)
sock_obj.bind((my_host, recv_port))
# Infinte loop
while 1:
data, address = sock_obj.recvfrom(1024)
sendto()
if data:
print "Server received data : ", str(data)
else:
print "No data recevied"
recvfrom()
break
sock_obj.sendto("Echo>=" + str(data), (address[0], send_port))
sock_obj.close()
if __name__ == '__main__':
print "UDPEchoServer", recv_port, send_port
test()
close()
UDPEchoServer
ソケットリンク
接続
socket()
bind()
Echo
Echo
recvfrom()
sendto()
ソケットリンク
開放
close()