winsockネットワークプログラミング1——Echoクライアント/サーバプログラム


ネットワーク構造モデルは主に2種類あり,分布式と集中式である.分散は、クライアント/サーバモデルとピアツーピアネットワークモデルに分けられます.
ネットワークモデルにおける集中式システムの利点は、構造が簡単で、安全性がよく、端末が安価で、欠点はホストに大きな圧力をもたらし、異なるユーザーに対して個別の相応の配置ができないことであり、主な応用例は自動ATM(ATM)、スーパーATM(POS)などである.
分散システムは、信頼性が高く、負荷が均等で、異なるニーズを満たすことができます.分散型のピアツーピアネットワークモデルは、また、無構造ネットワーク、有構造ネットワーク、ハイブリッドネットワーク、および集中型ネットワークに細分化することができる.クライアント・サーバ・モデルは、フラット・モデルと階層モデルに細分化できます.フラットモデル内のすべてのお客様が1つのサーバと通信します.階層モデルの1つのレベルのホストは、下位レベルのホストのサーバであり、上位レベルのホストのクライアントでもあります.
クライアント/サーバモデルは分散システムで最も広く使用されているネットワークモデルであり、多くの商業ソフトウェアはクライアント/サーバモデルを使用しており、重要な応用層プロトコルもこのモデルに基づいて設計されている.例えばHTTP、FTP、DNS、Telnetなどである.
以下はWinsockでシミュレートしたEchoサーバプログラムとクライアントプログラムです.まずは以下のEchoをご紹介します.Echoはインターネット上の標準的なプロトコルであり、非常に有用なデバッグとテストツールであり、Echoサーバは簡単に受信した情報をクライアントに送り返し、TCPもUDPプロトコルも使用でき、有名なポート番号は7である.以下、TCPに基づいてこのプロトコルを実装する.
サーバ側プログラム:
#include<stdio.h>
#include<winsock2.h>

#pragma comment(lib, "ws2_32")  /*winsock       */
 
#define ECHO_DEF_PORT  7   /*       */
#define ECHO_BUF_SIZE  256  /*      */

int main(int argc, char **argv)
{	
	WSADATA wsa_data;
	SOCKET echo_soc = 0,    /*  socket  */
		acpt_soc;

	struct sockaddr_in serv_addr,   /*socket     */
						clnt_addr;   /*socket     */
	unsigned short port = ECHO_DEF_PORT;
	int result = 0;
	int addr_len = sizeof(struct sockaddr_in);
	char recv_buf[ECHO_BUF_SIZE];

	if(argc == 2)
	{
		port = atoi(argv[1]);
	}

	WSAStartup(MAKEWORD(2,0), &wsa_data);   /*   winsock  */
	echo_soc = socket(AF_INET, SOCK_STREAM, 0);

	/*socket     */
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	serv_addr.sin_addr.S_un.S_addr = INADDR_ANY;

	result = bind(echo_soc, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
	if(result == SOCKET_ERROR)
	{
		printf("[Echo Server] bind error:%d
", WSAGetLastError()); closesocket(echo_soc); return -1; } listen(echo_soc, SOMAXCONN); printf("[Echo server] is running……
"); while(1) { acpt_soc = accept(echo_soc, (struct sockaddr*)&clnt_addr, &addr_len); if(acpt_soc == INVALID_SOCKET) { printf("[Echo Server] accept error:%d
", WSAGetLastError()); break; } result = recv(acpt_soc, recv_buf, ECHO_BUF_SIZE, 0); if(result > 0) { recv_buf[result] = 0; printf("[Echo Server] receives:\"%s\", from %s\r
", recv_buf, inet_ntoa(clnt_addr.sin_addr)); result = send(acpt_soc, recv_buf, result, 0); } closesocket(acpt_soc); } closesocket(echo_soc); WSACleanup(); return 0; }
クライアントプログラム:
#include<stdio.h>
#include<winsock2.h>   /*winsock2.h     windows.h*/

#pragma comment(lib, "ws2_32")   /*  winsock         */

#define ECHO_DEF_PORT   7     /*       */
#define ECHO_BUF_SIZE   256   /*      */


int main(int argc, char **argv)
{
	WSADATA wsa_data;      /*                */
	SOCKET echo_soc = 0;   /*socket  */
	struct sockaddr_in serv_addr;   /*     */
	unsigned short port = ECHO_DEF_PORT;
	int result = 0, send_len = 0;
	char *test_data = "Hello world!", recv_buf[ECHO_BUF_SIZE];

	if(argc < 2)
	{
		printf("input %s server_address [port]
", argv[0]); return -1; } if(argc >=3) { port = atoi(argv[2]); } WSAStartup(MAKEWORD(2,0), &wsa_data); /* winsock */ send_len = strlen(test_data); /* */ serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); /* */ serv_addr.sin_addr.S_un.S_addr = inet_addr(argv[1]); /* ascii IP */ if(serv_addr.sin_addr.S_un.S_addr == INADDR_NONE) { printf("[ECHO] invalid address
"); return -1; } echo_soc = socket(AF_INET, SOCK_STREAM, 0); /* socket*/ result = connect(echo_soc, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if(result == 0) /* */ { result = send(echo_soc, test_data, send_len, 0); result = recv(echo_soc, recv_buf, ECHO_BUF_SIZE, 0); /* */ } if(result > 0) { recv_buf[result] = 0; /* null*/ printf("[Echo Client] receives:\"%s\"\r
", recv_buf); } else { printf("[Echo Client] error:%d.\r
", WSAGetLastError()); } closesocket(echo_soc); WSACleanup(); return 0; }