欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

简单的服务端和客户端通信的一个程序

程序员文章站 2022-06-06 16:42:13
...

先写服务端,再写客户端,然后运行服务端,再运行客户端

#include<WinSock2.h> //socket:API 2.2
#include<stdio.h>

#pragma comment(lib,"ws2_32.lib")//加载静态库,提供对网络相关API的支持
/*
*套接字:
*IP、端口号 ,套接字绑定,
*/

int main()
{
	//加载套接字库,确定socket的版本
	WORD wVersionRequested;
	wVersionRequested = MAKEWORD(1, 1);//1.1版本
	WSADATA wsaData;
	//使用Socket的程序在使用Socket之前必须调用WSAStartup函数。以后应用程序就可以调用所请求的Socket库中的其它Socket函数了
	int nErr  = WSAStartup(wVersionRequested,&wsaData);
	if(nErr != 0)
	{
		printf("加载套接字库失败\n");
	}
	//检查下套接字库版本是否一致
	if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		printf("加载套接字库版本不一致\n");
		return 0;
	}
	//创建套接字,用于监听
	//Socket类型:流式套接字SOCK_STREAM, TCP   数据报套接字SOCK_DGRAM UDP 原始套接字SOCK_RAW
	SOCKET sockSrv = socket(AF_INET,//地址族,internet协议
		                    SOCK_STREAM,//套接字类型
							0);//0,会根据地址族和套接字类型自动选择合适的协议

	//htonl: host net
	//SOCKADDR_IN 用来处理网络通信的地址,一般用SOCKADDR_IN(区分了地址和端口),最后再强制转换为SOCKADDR作为参数传给系统函数
	SOCKADDR_IN addrSrv;                //INADDR_ANY表示本机所有IP
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//将主机的unsigned long值转换成网络字节顺序(32位)
	                                            //(一般主机跟网络上传输的字节顺序是不通的,分大小端),函数返回一个网络字节顺序的数字。
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(9880);//Host to Network Short

	//绑定套接字
	if(SOCKET_ERROR == bind(sockSrv,
		(SOCKADDR*)&addrSrv,//套接字的本地地址信息
		sizeof(SOCKADDR)//地址结构体大小
		))
	{
		printf("绑定套接字失败\n");
			return 0;
	}

	//将套接字设为监听模式
	if(SOCKET_ERROR == listen(sockSrv,
		                      5//等待连接队列的最大长度
		                      ))
	{
		printf("监听失败\n");
			return 0;
	}


	SOCKADDR_IN addrClient;//客户端地址信息
	int nlength = sizeof(SOCKADDR);
	while(1)
	{
		//接收客户端连接请求
		SOCKET sockConn = accept(sockSrv,//已经设置为监听状态的套接字
			              (SOCKADDR*)&addrClient,//用来接收连接上服务器的客户端的IP地址信息和端口信息
			              &nlength//地址信息的长度
			              );

		char szSendBuffer[100];
		sprintf_s(szSendBuffer, "服务器:欢迎来自%s的张鸿麟", inet_ntoa(addrClient.sin_addr));
		//inet_ntoa(addrClient.sin_addr);//获取它的IP地址

		//发送数据
		send(sockConn,//已经建立连接的套接字
			szSendBuffer,//一个buffer,待发送数据
			strlen(szSendBuffer) + 1,//发送字符串的长度
			0);

		//接收数据
		char szRecvBuffer[100];

		recv(sockConn, szRecvBuffer, 100, 0);

		printf("客户端发来的消息:%s", szRecvBuffer);
	}

	return 0;
}

客户端代码:

#include<WinSock2.h> //socket:API 2.2
#include<stdio.h>

#pragma comment(lib,"ws2_32.lib")//加载静态库

int main()
{
	//加载套接字库,确定socket的版本
	WORD wVersionRequested;
	wVersionRequested = MAKEWORD(1, 1);//1.1版本
	WSADATA wsaData;

	int nErr = WSAStartup(wVersionRequested, &wsaData);
	if(nErr != 0)
	{
		printf("加载套接字库失败\n");
	}
	//检查下套接字库版本是否一致
	if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
	{
		printf("加载套接字库版本不一致\n");
		return 0;
	}

	//前面和服务端一样

	//创建套接字
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);

	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.0.102");
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(9880);

	//向服务器发出连接请求
	if(SOCKET_ERROR == connect(sockClient,//
		(SOCKADDR*)&addrSrv,//服务器地址信息
		sizeof(SOCKADDR))
		)
	{
		printf("连接服务器失败\n");
		return 0;
	}

	while(1)
	{
		//接收数据
		char szRecvBuffer[100];

		recv(sockClient, szRecvBuffer, 100, 0);

		//打印接收数据
		printf("客服端接受的数据:\n%s\n", szRecvBuffer);

		//发送数据
		char szSendBuffer[100] = "这是一条来自客户端的消息";
		send(sockClient, szSendBuffer, strlen(szSendBuffer) + 1, 0);
		

	}

	return 0;
}

运行服务端再运行客户端:

服务端:

简单的服务端和客户端通信的一个程序

客户端:

简单的服务端和客户端通信的一个程序