【Socket编程】windows平台实现TCP客户端/服务器端


TCP socket 通信过程

windows代码示例:

该示例为client从server收到一条消息:hello world!

/*tcp_client_win.c*/
#include 
#include 
#include 
void ErrorHandling (char *message);

int main(int argc,char* argv[]){
	WSADATA wsaData;
	SOCKET hSocket;
	SOCKADDR_IN servAddr;

	char message[30];
	int strLen;

	if(argc != 3){
		printf("Usage:&s  \n,argv[0]");
		exit(1);
	}

	if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
		ErrorHandling("WSAStartup() error!");

	hSocket = socket (PF_INET,SOCK_STREAM,0);
	if(hSocket == INVALID_SOCKET)
		ErrorHandling("hSocket() error");

	memset(&servAddr,0,sizeof(servAddr));
	servAddr.sin_family=AF_INET;
	servAddr.sin_addr.s_addr=inet_addr(argv[1]);
	servAddr.sin_port=htons(atoi(argv[2]));

	if(connect(hSocket,(SOCKADDR*)&servAddr,sizeof(servAddr)) == SOCKET_ERROR)
		ErrorHandling("connect() error!");

	strLen = recv(hSocket,message,sizeof(message)-1,0);
	if(strLen == -1)
		ErrorHandling("read() error!");


	printf("message from server : %s \n",message);

	closesocket(hSocket);
	WSACleanup();
	return 0;

}

void ErrorHandling(char* message)
{
	fputs(message,stderr);
	fputs("\n",stderr);
	exit(1);
}
/*tcp_server_win.c*/
#include 
#include 
#include 
void ErrorHanding(char* message);

int main(int argc, char  *argv[])
{

	WSADATA wsaData;
	SOCKET hServSock,hClntSock;
	SOCKADDR_IN servAddr,clntAddr;

	int szClntAddr;//
	char message[]="hello world!";
	if(argc != 2)
	{
		printf("Usage : %s \n",argv[0]);
		exit(1);
	}

	if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
		ErrorHanding("WSAStartup() error!");

	hServSock = socket(PF_INET,SOCK_STREAM,0);
	if(hServSock == INVALID_SOCKET)
		ErrorHanding("socket() error");

	memset(&servAddr,0,sizeof(servAddr));
	servAddr.sin_family=AF_INET;
	servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
	servAddr.sin_port=htons(atoi(argv[1]));

	if(bind(hServSock,(SOCKADDR*)&servAddr,sizeof(servAddr))==SOCKET_ERROR)
		ErrorHanding("bind() error!");

	if(listen(hServSock,5)==SOCKET_ERROR)
		ErrorHanding("listen() error");

	szClntAddr = sizeof(clntAddr);
	hClntSock=accept(hServSock,(SOCKADDR*)&clntAddr,&szClntAddr);
	if(hClntSock==INVALID_SOCKET)
		ErrorHanding("accept() error!");

	send(hClntSock,message,sizeof(message),0);
	closesocket(hClntSock);
	closesocket(hServSock);
	WSACleanup();
	return 0;
}
void ErrorHanding(char * message)
{
	fputs(message,stderr);
	fputs("\n",stderr);
	exit(1);
}

实现迭代服务器端/客户端

之前讨论的hello world 服务器端处理完一个连接请求后立即退出,连接请求队列实际上没有任何意义,但这并非我们想象的服务器端,设置好等待队列的大小后,应向所有的客户端提供服务。

image-20220305203337525

/*echo_client_win.c*/
#include 
#include 
#include 
#include 

#define BUF_SIZE 1024;
void ErrorHanding(char *message);

int main(int argc, char  *argv[])
{
	WSADATA wsaData;
	SOCKET hSocket;
	char message[BUF_SIZE];
	int strLen;
	SOCKADDR_IN servAdr;

	if(argc!=3){
		printf("Usage:%s  \n",argv[0]);
		exit(1);
	}
	if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
		ErrorHanding("WSAStartup() error!");

	hSocket = socket(PF_INET,SOCK_STREAM,0);
	if(hSocket==INVALID_SOCKET)
		ErrorHanding("scoket() error!");

	memset(&servAdr,0,sizeof(servAdr));
	servAdr.sin_family=AF_INET;
	servAdr.sin_addr.s_addr=inet_addr(argv[1]);
	servAdr.sin_port=htons(atoi(argv[2]));

	if(connect(hSocket,(SOCKADDR*)&servAdr,sizeof(servAdr))==SOCKET_ERROR)
		ErrorHanding("connect() error!");
	else
		puts("connected ........");

	while(1){
		fputs("iput memset(Q to quit):",stdout);
		fgets(memset,BUF_SIZE,stdin);

		if(!strcmp(message,"q\n")|| !strcmp(message,"Q\n"))
			break;

		send(hSocket,message,strlen(message),0);
		strLen=recv(hSocket,message,BUF_SIZE-1,0);
		message[strLen]=0;
		printf("message from server : %s",message);
		}
	closesocket(hSocket);
	WSACleanup();
	return 0;
}

void ErrorHanding(char* message){
	fputs(message,stderr);
	fputs('\n',stderr);
	exit(1);
}
/*echo_server_win.c*/
#include 
#include 
#include 
#include 

#define BUF_SIZE 1024

void ErrorHanding(char * message);

int int main(int argc, char  *argv[])
{
	WSADATA wsaData;
	SOCKET hServSock,hClntSock;
	char message[BUF_SIZE];
	int strLen,i;
	SOCKADDR_IN hServSock,hClntSock;
	int clntAdrSize;

	if(argc!=2){
		printf("Usage:%s \n",argv[0]);
		exit(1);
	}

	if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
		ErrorHanding("WSAStartup error!");

	hServSock = socket(PF_INET,SOCK_STREAM,0);
	if(hServSock==INVALID_SOCKET)
		ErrorHanding("socket error!");

	memset(&servAdr,0,sizeof(servAdr));
	servAdr.sin_family=AF_INET;
	servAdr.sin_addr.s_addr=htonl(INADDR_ANY);
	servAdr.sin_port=htons(atoi(argv[1]));

	if(bind(hServSock,(SOCKADDR*)&servAdr,sizeof(servAdr))==SOCKER_ERROR)
		ErrorHanding("bind() error!");

	if(listen(hServSock,5)==SOCKER_ERROR)
		ErrorHanding("listen() error!");

	clntAdrSize = sizeof(clntAdr);

	for(i=0;i<5;i++){
		hClntSock=accept(hServSock.(SOCKADDR*)&clntAdr,&clntAdrSize);
		if(hClntSock==-1)
			ErrorHanding("accept() error!");
		else
			printf("connected client %d \n",i+1);

		while((strLen=recv(hClntSock,message,BUF_SIZE,0))!=0)
			send(hClntSock,message,strLen,0);

		closesocket(hClntSock);
	}
	closesocket(hServSock);
	WSACleanup();
	return 0;
}

void ErrorHanding(char * message){
	fputs(message,stderr);
	fputs('\n'stderr);
	exit(1);
}