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()
© Copyright 2024 ExpyDoc