第14章 网络编程

基于TCP协议的SOCKET通信

服务器代码

#include<WinSock2.h>//使用WinSocket库中的函数
#include<stdio.h>//使用C语言标准输入输出函数
#pragma comment(lib,"ws2_32.lib")//需要加上这个链接库不然WSAStartup报错
void main()
{
	WORD wVersionRequested;//保存版本号
	WSADATA wsaData;//保存加载版本的库信息
	int err;

	wVersionRequested=MAKEWORD(1,1);//生成版本号,如果版本是2.1则MAKEWORD(2,1);一个WORD占16位,第一参数是低八位,第二个参数是高八位,第八位是主版本,高八位是﹣版本,对于版本是2.1来说2是主版本,1是副版本号
	err=WSAStartup(wVersionRequested,&wsaData);//加载套接字库,进行版本协商,如果没有wVersionRequested所指的版本,就找相近的,wsaData中wVersion存储要使用的版本号,wHeighVersion存储最高版本号
	if (err!=0)//加载失败
	{
		return;
	}

	if (LOBYTE(wsaData.wVersion)!=1||
		HIBYTE(wsaData.wVersion!=1))//加载版本和请求版本不一致
	{
		WSACleanup();
		return;
	}
	//以上套接字版本加载完成
	//开始创建套接字
	SOCKET socketser=socket(AF_INET,SOCK_STREAM,0);//第一个参数是通信区域,Windows Sockets只只支持网际域所以必须是AF_INET,
	//第二个参数指定产生流式套接字还是数据报套接字,TCP使用流式套接字SOCK_STREAM,UDP使用SOCK_DGRAM
	//第三个参是与特定的地址家族相关的协议,设置成0时自动选择一个合适的协议。
																
	SOCKADDR_IN addrser;//指定套接字的本地地址信息,包括IP和端口号等
	addrser.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//设置可连接客户端的IP,设置INADDR_ANY表示任何客户端都可以连接,htonl()作用是将u_long从主机字节序转换为网络字节序,
	addrser.sin_family=AF_INET;
	addrser.sin_port=htons(6000);//设置服务器程序端口号,端口号大于1024,htons()函数是将u_short从主机字节序转换为网络字节序。

	//绑定字节序
	bind(socketser,(SOCKADDR*)&addrser,sizeof(SOCKADDR));//把套接字绑定在端口上,
	//设置套接字为监听模式,准备接收客户端请求
	listen(socketser,5);//第二个参数是等待连接队列最大长度。

	SOCKADDR_IN addrcli;//用于存储客户端套接字地址信息
	int len=sizeof(SOCKADDR);

	while (1)
	{
		SOCKET socketcli=accept(socketser,(SOCKADDR*)&addrcli,&len);//返回客户端socket用来通讯,获取客户端套接字地址信息
		char sendbuf[100];
		sprintf(sendbuf,"welcome %s to service",inet_ntoa(addrcli.sin_addr));//格式化要发送的数据;
		send(socketcli,sendbuf,strlen(sendbuf)+1,0);
		char recvbuf[100];
		recv(socketcli,recvbuf,100,0);
		printf("%s\n",recvbuf);
		closesocket(socketcli);
	}
}

 客户端代码

#include <WinSock2.h>
#include <stdio.h>
#pragma comment (lib,"ws2_32.lib")

void main()
{
	WORD wVersionRequested=MAKEWORD(1,1);
	WSADATA wsaData;
	int err=WSAStartup(wVersionRequested,&wsaData);
	if (err!=0)
	{
		return;
	}
	if (LOBYTE(wVersionRequested)!=1||
		HIBYTE(wVersionRequested)!=1)
	{
		WSACleanup();
		return;
	}
	SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0); //三个参数分别表示:地址族,流还是数据报类型,协议(0表示由系统选)
	SOCKADDR_IN addrser;//指定套接字的本地地址信息,包括IP和端口号等
	addrser.sin_addr.S_un.S_addr=inet_addr("172.18.40.21");//inet_addr将点分十进制地址转换为一个无符号整形表示形式,127.0.0.1是回送地址,指本地机,一般用来测试使用。
	addrser.sin_family=AF_INET;
	addrser.sin_port=htons(6000);//设置服务器程序端口号,端口号大于1024,htons()函数是将u_short从主机字节序转换为网络字节序。
	connect(sockClient,(SOCKADDR*)&addrser,sizeof(SOCKADDR));
	char recvBuf[100];
	recv(sockClient,recvBuf,100,0);
	printf("%s\n",recvBuf);
	//测试发送
	send(sockClient,"Client",strlen("Client")+1,0);
	closesocket(sockClient);//关闭套接字
	WSACleanup();//清理套接字dll
	system("pause");
}

基于UDP协议的SOCKET通信

服务器

//基于UDP协议
#include<WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")

void main()
{
	WORD wVersionRequested=MAKEWORD(1,1);
	WSADATA wsaData;
	int err=WSAStartup(wVersionRequested,&wsaData);
	if (err!=0)
	{
		return;
	}
	if (LOBYTE(wsaData.wVersion)!=1||
		HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();
		return;
	}

	SOCKET socketser=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrin;
	addrin.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
	addrin.sin_family=AF_INET;
	addrin.sin_port=htons(6000);
	bind(socketser,(SOCKADDR*)&addrin,sizeof(SOCKADDR));

	char recvbuf[100];
	char sendbuf[100];
	char tempbuf[100];

	SOCKADDR_IN addrcli;
	int len=sizeof(addrcli);
	while (1)
	{
		//等待接收数据
		recvfrom(socketser,recvbuf,100,0,(SOCKADDR*)&addrcli,&len);
		if (recvbuf[0]=='q')
		{
			sendto(socketser,"q",strlen("q")+1,0,(SOCKADDR*)&addrcli,len);
			printf("chat end!\n");
			break;
		}
		sprintf(tempbuf,"%s say:%s",inet_ntoa(addrcli.sin_addr),recvbuf);
		printf("%s\n",tempbuf);
		printf("Please input data:\n");
		gets(sendbuf);
		sendto(socketser,sendbuf,strlen(sendbuf)+1,0,(SOCKADDR*)&addrcli,len);


	}
	closesocket(socketser);
	WSACleanup();
}

客户端

//基于UDP协议
#include<WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")

void main()
{
	WORD wVersionRequested=MAKEWORD(1,1);
	WSADATA wsaData;
	int err=WSAStartup(wVersionRequested,&wsaData);
	if (err!=0)
	{
		return;
	}
	if (LOBYTE(wsaData.wVersion)!=1||
		HIBYTE(wsaData.wVersion)!=1)
	{
		WSACleanup();
		return;
	}

	SOCKET socketser=socket(AF_INET,SOCK_DGRAM,0);
	SOCKADDR_IN addrin;
	addrin.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
	addrin.sin_family=AF_INET;
	addrin.sin_port=htons(6000);

	char recvbuf[100];
	char sendbuf[100];
	char tempbuf[100];

	int len=sizeof(SOCKADDR);
	while (1)
	{
		//等待接收数据
		printf("Please input data:\n");
		gets(sendbuf);
		sendto(socketser,sendbuf,strlen(sendbuf)+1,0,(SOCKADDR*)&addrin,len);
		recvfrom(socketser,recvbuf,100,0,(SOCKADDR*)&addrin,&len);
		
		if (recvbuf[0]=='q')
		{
			sendto(socketser,"q",strlen("q")+1,0,(SOCKADDR*)&addrin,len);
			printf("chat end!\n");
			break;
		}
		sprintf(tempbuf,"%s say:%s",inet_ntoa(addrin.sin_addr),recvbuf);
		printf("%s\n",tempbuf);

	}
	closesocket(socketser);
	WSACleanup();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值