【免杀前置课——Windows编程】十五、网络编程——C/S,B/S模式分别是什么?WinSocket、Socket传输的定义和其特点、实现简易通信(附代码)

网络编程

网络分为C/S,B/S两种模式。

C/S:客户端/服务器模式:

服务器端:
首先服务器先启动,并根据客户端请求做出相应的响应。
1、打开一个通信通道,在某一端口接受客户端请求。
2、接受到客户端请求后处理请求并返回信息给客户端。
3、继续等待客户端请求直到关闭服务器。
客户端:
1、打开一个通信通道,并连接到服务器所在主机的特定端口。
2、向服务器发送请求,等待并接收响应,继续发送请求。
3、关闭客户端。

B/S:浏览器/服务器架构模式。

这种架构浏览器是客户端的主要应用软件,主要事物逻辑在服务器实现,前端(浏览器)负责展示。

WinSocket:

Windows Sockets规范是一套开放的、支持多协议的Windows下的网络编程接口。目前实际应用中的Windwos Sockets规范主要有1.1版本和2.2版本,其中1.1版本只支持TCP/IP协议,而2.2支持多协议,并具有良好的向后兼容性。这俩版本对应的头文件分别是: WinSocket.h WinSocket2.h

Socket传输的定义和其特点

所谓socket通常也称作“套接字”,实现服务器和客户端之间的物理连接,并进行数据传输,主要有UDP和TCP两个协议
Socket处于网络协议的传输层
TCP协议:TCP (Transmission Control Protocol,传输控制协议)是面向连接的协议,也就是说,在收发数据前,必须和对方建立可靠的连接。一个TCP连接必须要经过三次“对话”才能建立起来,其中的过程非常复杂
UDP协议:UDP是一个非连接的协议,传输数据之前源端和终端不建立连接,当它想传送时就简单地去抓取来自应用程序的数据,并尽可能快地把它扔到网络上。
在发送端,UDP传送数据的速度仅仅是受应用程序生成数据的速度、计算机的能力和传输带宽的限制;
在接收端,UDP把每个消息段放在队列中,应用程序每次从队列中读一个消息段.

实现简易通信

服务器端

#include<WinSock2.h>
#include<Windows.h>
#include<iostream>
#include<ws2tcpip.h>
#pragma comment(lib,"ws2_32.lib")
#include<vector>
using std::vector;

vector<SOCKET> clientList;//保存多个线程的客户端
DWORD WINAPI revcMessage(LPVOID param)
{
	SOCKET client = (SOCKET)param;
	char buff[0x100]{ 0 };
	int recvSize = 0;
	while ((recvSize = recv(client,buff,0x100,0))>0)//接受消息的字节数判断是否大于0
	{
		for (int i = 0; i < clientList.size(); i++)//遍历进程中的每一个客户端线程
		{
			if (client != clientList[i])//判断是不是当前线程发的消息,若不是则发送给每个客户端
			{
				send(clientList[i], buff, recvSize, 0);
			}
		}
	}

	for (int i = 0; i < clientList.size(); i++)
	{
		if (clientList[i] == client)//判断哪一个客户端线程断开了连接
		{
			printf("客户端%u断开了连接\n", clientList[i]);
			closesocket(clientList[i]);
			clientList.erase(clientList.begin() + i);
		}
	}
	return 0;
}

int main()
{
	//1、初始化网络环境
	WSADATA data{ 0 };
	WSAStartup(MAKEWORD(2,2), &data);
	//2、创建Socket
	SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//用IPv4地址协议簇,TCP连接
	//3、指定IP地址和端口号
	sockaddr_in serverAddr{ 0 };
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(7777);
	inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);//InetPton函数将标准文本表示形式的 IPv4 或 IPv6 互联网网络地址转换为数字二进制形式
	//printf("%s\n", serverAddr.sin_addr);
	bind(server, (SOCKADDR*)&serverAddr, sizeof(serverAddr));//绑定函数将本地地址与套接字相关联。
	//4、监听
	listen(server, SOMAXCONN);
	//5、接受会话
	sockaddr_in clientAddr{ 0 };
	int size = sizeof(clientAddr);
	while (1)
	{
		//printf("等待客户端连接中......\n");
		SOCKET client = accept(server, (SOCKADDR*)&clientAddr, &size);//绑定将监听地址与套接字
		clientList.push_back(client);
		//创建线程实现并发通信
		CreateThread(NULL, NULL, revcMessage, (LPVOID)client, NULL, NULL);
		printf("客户端%u连接到了服务器\n",client);
		//char buff[0x100]{ 0 };
		//recv(client, buff, 0X100, 0); //recv函数从连接的套接字或绑定的无连接套接字接收数据
		//printf("client:%s\n", buff);
		//send(client, "有话说,没话走!", 16, 0);
	}
	closesocket(server);
	return 0;
}

客户端

#include<WinSock2.h>
#include<Windows.h>
#include<iostream>
#include<ws2tcpip.h>

#pragma comment(lib,"ws2_32.lib")

DWORD WINAPI revcMessage(LPVOID param)
{
	SOCKET client = (SOCKET)param;
	char buff[0x100]{ 0 };
	while (recv(client, buff, 0x100, 0) > 0)
	{
		printf("%s\n", buff);

	}
	return 0;
}

int main()
{
	//1、初始化网络环境
	WSADATA data{ 0 };
	WSAStartup(MAKEWORD(2, 2), &data);
	//2、创建Socket
	SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//用IPv4地址协议簇,TCP连接
	//3、指定IP地址和端口号
	sockaddr_in serverAddr{ 0 };
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(7777);
	inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);//InetPton函数将标准文本表示形式的 IPv4 或 IPv6 互联网网络地址转换为数字二进制形式
	//4、连接
	int result = connect(client, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
	if (result)
	{
		printf("连接服务器失败\n");
	}
	HANDLE hThread = CreateThread(NULL, NULL, revcMessage, (LPVOID)client, NULL, NULL);
	char buff[0x100]{ 0 };
	while (scanf_s("%s",buff,0x100) && strcmp(buff,"exit"))//接受用户输入
	{
		send(client, buff, strlen(buff) + 1, 0);
	}
	closesocket(client);
	CloseHandle(hThread);
	/*send(client, "我有话说\n", 8, 0);
	char buff[0x100]{ 0 };
	recv(client, buff, 0x100, 0);
	printf("server:%s", buff);
	system("pause");*/
	return 0;
}




在这里插入图片描述
若不点击服务器端则一直等待客户端消息。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

webfker from 0 to 1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值