UDP/IP 事件选择模型

电力电子技术(13)——大功率可控整流电路 目录引言2.6.1 带平衡电抗器的双反星形可控整流电路电路结构的特点接平衡电抗器的原因平衡电抗器使得两组三相半波整流电路同时导电的原理分析谐波分析2.6.2 多重化整流电路概述原理目标1)移相多重联结2)多重联结电路的顺序控制3重晶闸管整流桥顺序控制带平衡电抗器的双反星形可控整流电路(是多重化整流电路的重要形式之一)的特点:适用于低电压、大电流的场合。多重化整流电路的特点:绕组的极性相反的目的:消除直流磁通势如图所示,虽然两组相电流的瞬时值不同,但是平均电流相等而绕组的极性相反,所以直流安匝(电流*匝数)互 阅读详情

事件选择模型核心:

为每一个socket创建一个事件对象,将socket和对应的事件对象绑定到一起,并投递给操作系统,由操作系统帮我们进行监视,当对应的socket有响应,该对应的事件会被置成有信号,我们获取该信号,进行分类处理。

UDP/IP 事件选择模型:

UDP/IP 是面向非连接的,不可靠的,基于数据报的传输层协议;

对于服务端只有一个socket(服务端socket),直接创建一个事件对象,将该socket和对应的事件对象进行绑定,并投递给系统,之后等待信号,获取信号,之后进行分类处理。

事件选择模型的逻辑:

1. 创建一个事件对象:

WSAEVENT WSAAPI WSACreateEvent();

2. 绑定并投递

  int WSAAPI WSAEventSelect
  (	// 函数功能:给事件绑上socket与对应的操作,并投递给操作系统
  		SOCKET   s,				// 被绑定的socket 最终,每个socket都会被绑定一个事件
  		WSAEVENT hEventObject,	// 事件对象 逻辑,就是讲参数1与参数2绑定在一起
  		long     lNetworkEvents	// 具体的事件	FD_READ FD_WRITE ...
  );

3. 循环等待事件产生信号

  DWORD WSAAPI WSAWaitForMultipleEvents(	// 作用:等待事件产生信号
  DWORD          cEvents,		// 事件个数
  const WSAEVENT *lphEvents,	// 事件列表
  BOOL           fWaitAll,		// 事件等待方式
  DWORD          dwTimeout,		// 超时间隔
  BOOL           fAlertable		// 这里填FALSE
  );

4. 获取信号,进行分类处理

int WSAAPI WSAEnumNetworkEvents(	// 获取事件类型,并将事件上的信号重置
  SOCKET             s,					// 对应的socket
  WSAEVENT           hEventObject,		// 对应的事件
  LPWSANETWORKEVENTS lpNetworkEvents	// 触发的事件类型 声明一个结构体指针
);

服务端代码:

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

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

/*
	UDP/IP (User Datagram Protocol/Internet Protocol) 用户数据报协议
	TCP/IP 协议的特点:
		面向连接的,可靠的,基于字节流的传输层协议。
	UDP/IP 协议的特点:
		面向非连接的,不可靠的,基于数据报的传输层协议。
	1.基本C/S模型中服务端代码:
		UDP/IP 与 TCP/IP 的区别:
			UDP/IP:
				是面向非连接的,不用进行listen(进行监听)、不进行accept(接收连接)
				与客户端进行收发消息调用的是 recvfrom、sendto函数
			TCP/IP:
				是面向连接的,进行listen(进行监听)、进行accept(接收连接 本质创建客户端socket)
				与客户端进行收发消息调用的是 recv、send函数
	2.select模型服务端代码:
			UDP/IP:
				UDP/IP协议的C/S模型不存在傻等的问题,而select模型只是能让recvfrom更灵活一些
					select 代码逻辑:
						1.所有的socket装进一个集合FD_SET UDP只有一个socket即将服务端的socket装进集合中就可以了
						2.通过select函数,检测中的socket集合中那个有响应了,就是检测有没有消息来了,
						3.有消息了,则进行处理 调用 recvfrom
			TCP/IP:
				TCP/IP协议的C/S模型中accept、recv存在傻等问题,select模型是为了解决accept、recv傻等问题,
					select 代码逻辑:
						1.每个客户端都有socket,服务器也有自己的socket,将所有的socket装进一个数据结构里,即数组 fd_set
						2.通过select函数,遍历1中socket数组,当某个socket有响应,select就会通过其参数/返回值反馈出来,之后做相应的处理
						3.处理有响应的socket,
							判断检测到是的服务端socket,有客户端来链接了,调用accept(创建客户端socket)
							判断检测到的是客户端socket,客户端请求通信,调用send或者recv进行发收消息

windows处理用户行为的两种方式:
消息机制:
	核心:消息队列
		处理过程:
			所有的用户操作,比如鼠标,按下键盘键,点击软件的按钮... 等,
			所有的操作均是依次按顺序被记录,装进一个队列中
		特点:
			消息队列由操作系统维护,我们把消息取出,然后进行分类处理

事件机制:
	核心:事件集合
		处理过程:
			根据需求,为用户的特定操作绑定一个事件,事件由我们自己调用API创建,需要多少创建多少
			将事件投递系统,系统就帮我们进行监视着,创建事件不能无限创建,创建多了,系统就会卡
			如果操作发生了,比如用户按鼠标,该事件会被置成有信号
			直接获取有事件的信号,进行处理
		特点:
			所有的事件都是我们自定义的,系统只是我们置成有无信号

	3.事件选择模型服务端代码:
		UDP/IP事件选择:
			事件选择模型是为每一个socket绑定一个事件对象,(而UDP/IP服务端代码只有一个socket)
			并投递给操作系统,系统为我们进行监视着,当有客户端发来了消息,该事件就会被置成有信号的,
			那么我们获取该有信号的事件,进行处理
				代码逻辑:
					第一步:创建一个事件对象(变量)	WSACreateEvent
					第二步:将事件与socket绑定到一起,并指定监视类型(recvfrom,sendto)并投递给系统	WSAEventSelect
					第三步:循环等待事件产生信号	WSAWatiForMultipleEvents	该函数等待过程将所在线程挂起,释放CPU时间
					第四步:有信号的话,就进行分类处理		WSAEnumNetworkEvents
		
		TCP/IP事件选择:
			整体逻辑跟UDP/IP事件选择模型一致,注意的是TCP/IP是面向连接的,要进行accept处理
				代码逻辑:
					第一步:创建一个事件对象(变量)	WSACreateEvent
					第二步:为每一个事件对象绑定一个socket以及操作accept、read、close...,并投递给系统
					第三步:查看事件是否有信号		WSAWaitForMultipleEvents
					第四步:有信号的话就进行分类处理	WSAEnumNetworkEvents
*/
// 声明变量接收创建事件对象
HANDLE nCreEvn;

// 1.打开网络库 2.校验版本号
void OpenAndCheckWSAStartup();

// 3.创建服务端socket
SOCKET Sock_Server();

// 全局声明要创建 创建服务端socket
SOCKET socketServer;

// 4.绑定地址与端口号
void Bind(SOCKET sock);

// 5.实现事件选择模型核心代码
void Event_Select(SOCKET sock);

// 监视窗口回调函数
BOOL WINAPI fun(DWORD dwCtrlType);

int main()
{
	// 监视关闭窗口按钮
	SetConsoleCtrlHandler(fun, TRUE);

	// 1.打开网络库 2.校验版本号
	OpenAndCheckWSAStartup();

	// 3.创建服务端socket
	socketServer = Sock_Server();

	// 4.绑定地址与端口号
	Bind(socketServer);

	// 5.核心事件选择模型
	Event_Select(socketServer);

	//关闭事件对象
	WSACloseEvent(nCreEvn);
	//关闭socket
	closesocket(socketServer);
	//关闭网络库
	WSACleanup();
	system("pause");
	return 0;
}

// 1.打开网络库 2.校验版本号
void OpenAndCheckWSAStartup()
{
	// 定义WSAStartup函数中参数1 所需的版本号
	WORD wVersionRequestd = MAKEWORD(2, 2);	// 设置2.2版本号
	// 声明WSAStartup函数中参数1 所需的结构体
	WSADATA WSAData;
	// 打开网络库
	int nRet = WSAStartup(wVersionRequestd, &WSAData);
	if (0 != nRet)
	{
		//出错了
		int a = WSAGetLastError();
		printf("网络库打开失败 %d\n", a);
		return;
	}
	// 检验版本号
	if (2 != HIBYTE(WSAData.wVersion) || 2 != LOBYTE(WSAData.wVersion))
	{
		printf("校验版本号错误\n");
		// 关闭网络库
		WSACleanup();
		return;
	}
}
// 3.创建服务端socket
SOCKET Sock_Server()
{
	// 创建服务端 socket
	SOCKET sock_server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	// 判断服务端socket是否成功创建
	if (INVALID_SOCKET == sock_server)
	{
		//出错了
		int a = WSAGetLastError();
		printf("创建服务端socket失败,获取的错误码为 %d\n", a);
		//关闭网络库
		WSACleanup();
		return 0;
	}
	return sock_server;
}
// 4.绑定地址与端口号
void Bind(SOCKET sock)
{
	// 声明bind函数参数2所需的 结构体
	struct sockaddr_in sockMsg;
	// 给结构体成员赋值
	sockMsg.sin_family = AF_INET;
	sockMsg.sin_port = htons(12345);
	sockMsg.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	// 绑定地址与端口号
	int nRet = bind(sock, (struct sockaddr*)&sockMsg, sizeof(sockMsg));
	// 判断是否成功绑定地址与端口号
	if (SOCKET_ERROR == nRet)
	{
		//出错了
		int a = WSAGetLastError();
		printf("绑定地址与端口号失败,获取的错误码为 %d\n", a);
		//关闭socket
		closesocket(sock);
		//关闭网络库
		WSACleanup();
		return;
	}
}
// 5.实现事件选择模型核心代码
void Event_Select(SOCKET sock)
{
/*int WSAAPI WSAEventSelect
  (	// 函数功能:给事件绑上socket与对应的操作,并投递给操作系统
  		SOCKET   s,				// 被绑定的socket 最终,每个socket都会被绑定一个事件
  		WSAEVENT hEventObject,	// 事件对象 逻辑,就是讲参数1与参数2绑定在一起
  		long     lNetworkEvents	// 具体的事件	FD_READ FD_WRITE ...
  );
*/
/* DWORD WSAAPI WSAWaitForMultipleEvents(	// 作用:等待事件产生信号
  DWORD          cEvents,		// 事件个数
  const WSAEVENT *lphEvents,	// 事件列表
  BOOL           fWaitAll,		// 事件等待方式
  DWORD          dwTimeout,		// 超时间隔
  BOOL           fAlertable		// 这里填FALSE
*/
/*int WSAAPI WSAEnumNetworkEvents(	// 获取事件类型,并将事件上的信号重置
  SOCKET             s,					// 对应的socket
  WSAEVENT           hEventObject,		// 对应的事件
  LPWSANETWORKEVENTS lpNetworkEvents	// 触发的事件类型 声明一个结构体指针
);*/


	// 1.创建服务端socket对应的事件对象
	nCreEvn = WSACreateEvent();
	// 判断是否成功创建事件对象
	if (WSA_INVALID_EVENT == nCreEvn)
	{
		// 出错了
		int a = WSAGetLastError();
		printf("创建事件对象失败,获取的错误码为: %d\n", a);
		// 关闭socket
		closesocket(sock);
		// 关闭网络库
		WSACleanup();
		return;
	}
	// 2.将socket和对应的事件对象绑定到一起,并投递给系统
	int nEvnSel = WSAEventSelect(sock, nCreEvn, FD_READ | FD_WRITE);
	// 判断是否成功绑定并投递
	if (SOCKET_ERROR == nEvnSel)
	{
		// 出错了
		int a = WSAGetLastError();
		printf("绑定并投递失败,获取的错误码为: %d\n", a);
		// 关闭socket
		closesocket(sock);
		// 关闭事件对象
		WSACloseEvent(nCreEvn);
		// 关闭网络库
		WSACleanup();
		return;
	}
	// 3.循环等待事件
	while (1)
	{
		// 等待事件
		DWORD nWaiFor = WSAWaitForMultipleEvents(1, &nCreEvn, FALSE, WSA_INFINITE, FALSE);
		// 判断是否等待事件
		if (WSA_WAIT_FAILED == nWaiFor)
		{
			// 没有等待到事件
			int a = WSAGetLastError();
			printf("没有等待到事件,出现的错误码为: %d\n", a);
			// 直接退出函数
			break;
		}
		// 声明WSAEnumNetworkEvents函数中参数3所需的结构体
		WSANETWORKEVENTS NetworkEvents;
		// 4.等到了事件,进行列举事件
		int nEnm = WSAEnumNetworkEvents(sock, nCreEvn, &NetworkEvents);
		// 判断是否成功列举事件
		if (SOCKET_ERROR == nEnm)
		{
			//出错了
			int a = WSAGetLastError();
			printf("列举事件失败,获取的错误码为: %d\n", a);
			//函数调用失败
			continue;
		}
		// 5.成功列举事件,进行分类处理 FD_READ  FD_WRITE
		// 处理FD_READ
		if (NetworkEvents.lNetworkEvents & FD_READ)
		{
			// 通过列举函数参数3的结构体成员变量进行判断是否进行接收消息
			if (0 == NetworkEvents.iErrorCode[FD_READ_BIT])
			{
				// 声明发送对方(客户端)的结构体对象
				// 声明recvfrom函数中参数5所需的对方结构体对象
				struct sockaddr sockClient;
				// 获取对方结构体大小
				int len = sizeof(sockClient);
				// 声明recvfrom函数中参数2所需的 接收数据的缓存区字节数组
				char strBuf[548] = { 0 };
				int nRecv = recvfrom(sock, strBuf, 548, 0, &sockClient, &len);
				// 判断是否成功接收数据
				if (SOCKET_ERROR == nRecv)
				{
					//出错了
					int a = WSAGetLastError();
					printf("接收数据失败,获取的错误码为: %d\n", a);
				}
				// 打印数据
				printf("%s\n", strBuf);

				// 进行发送数据(给客户端发送数据)
				int nSend = sendto(sock, "send ok", sizeof("send ok"), 0, &sockClient, len);
				// 判断是否成功发送数据
				if (SOCKET_ERROR == nSend)
				{
					//出错了
					int a = WSAGetLastError();
					printf("发送数据失败,获取的错误码为: %d\n", a);
				}
			}
		}
		// 处理FD_WRITE
		if (NetworkEvents.lNetworkEvents & FD_WRITE)
		{
			// 通过列举函数参数3的结构体成员变量进行判断是否成功发送sendto
			if (0 == NetworkEvents.iErrorCode[FD_WRITE_BIT])
			{
				printf("成功发送\n");
			}
		}
	}
}
// 监视窗口回调函数
BOOL WINAPI fun(DWORD dwCtrlType)
{
	switch (dwCtrlType)
	{
	case CTRL_CLOSE_EVENT:
		// 关闭socket
		closesocket(socketServer);
		// 关闭对应的事件
		WSACloseEvent(nCreEvn);
		// 清理网络库
		WSACleanup();
		break;
	}
	return TRUE;
}

客户端代码:

#define _WINSOCK_DEPRECATED_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>

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

/*
	UDP/IP 基本C/S模型 客户端:
		与 UDP/IP 基本C/S模型 服务端代码的区别:
		代码基本一致,只有bind 函数有区别
		服务端需要进行绑定地址与端口号,因为服务端是一对多
		客户端只需要创建服务端地址与端口结构体,与服务端发送数据报时,
		  直接传递的是创建的结构体就可以了,不用进行绑定,因为服务端的ip与端口号固定不变的	

*/
// 1.打开网络库 2.校验版本号
void OpenAndCheckWSAStartup();

// 3.创建服务端socket
SOCKET Sock_Server();

// 全局声明要创建 创建客户端socket
SOCKET socketClient;

// 4.与客户端进行发收数据
void SendToAndRecvFrom(SOCKET sock);

int main()
{
	// 1.打开网络库 2.校验版本号
	OpenAndCheckWSAStartup();

	// 3.创建服务端socket
	SOCKET socketClient = Sock_Server();

	// 4.与客户端进行发收数据
	SendToAndRecvFrom(socketClient);

	//释放socket 
	closesocket(socketClient);
	//清理网络库
	WSACleanup();
	system("pause");
	return 0;
}

// 1.打开网络库 2.校验版本号
void OpenAndCheckWSAStartup()
{
	// 定义WSAStartup函数中参数1 所需的版本号
	WORD wVersionRequestd = MAKEWORD(2, 2);	// 设置2.2版本号
	// 声明WSAStartup函数中参数1 所需的结构体
	WSADATA WSAData;
	// 打开网络库
	int nRet = WSAStartup(wVersionRequestd, &WSAData);
	if (0 != nRet)
	{
		//出错了
		int a = WSAGetLastError();
		printf("网络库打开失败 %d\n", a);
		return;
	}
	// 检验版本号
	if (2 != HIBYTE(WSAData.wVersion) || 2 != LOBYTE(WSAData.wVersion))
	{
		printf("校验版本号错误\n");
		// 关闭网络库
		WSACleanup();
		return;
	}
}
// 3.创建服务端socket
SOCKET Sock_Server()
{
	// 创建服务端 socket
	SOCKET sock_server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	// 判断服务端socket是否成功创建
	if (INVALID_SOCKET == sock_server)
	{
		//出错了
		int a = WSAGetLastError();
		printf("创建服务端socket失败,获取的错误码为 %d\n", a);
		//关闭网络库
		WSACleanup();
		return 0;
	}
	return sock_server;
}
// 4.与客户端进行发收数据
void SendToAndRecvFrom(SOCKET sock)
{
	/*int recvfrom(
	  SOCKET   s,
	  char     *buf,
	  int      len,
	  int      flags,
	  sockaddr *from,
	  int      *fromlen
	);
	recvfrom函数:
		作用:得到当前服务端接收到的消息
		本质:复制	将协议缓存区的数据复制黏贴进自定义的buf
		与recv函数一样是进行接收消息,不同的是recv是傻等,recvfrom是死等
	参数1:客户端的socket
		特点:
			TCP是获取指定的,recv函数与客户端是1对1的关系 -- 傻等
			UDP是无差别获取,recvfrom函数与客户端是1对多的关系 -- 死等
	参数2:客户端消息的存储空间,也就是一个字符数组
		广域网:各级路由器上的MTU最小值是576字节
			tcp = 576 - 20(TCP包头) - 20(IP包头) = 536;
			udp = 576 - 8(UDP包头) - 20(IP包头) = 548;
	参数3:想要读取的字节个数, 参数2的字节数
	参数4:数据的读取方式
			0			从协议缓存区取一个数据报,然后就删除掉
			MSG_PEEK	取出数据报,但是协议缓存内不删除,一直残留,导致影响后面的数据读取
			MSG_OOB		带外数据
	参数5:对方的IP地址端口号
			此处结构体为相应的IP地址和端口号 struct sockaddr* sockClient; 填 &sockClient;
	参数6:参数5结构体的大小 int len = sizeof(&sockClient);	填 &len;
	*/
	/*int sendto(
	  SOCKET         s,
	  const char     *buf,
	  int            len,
	  int            flags,
	  const sockaddr *to,
	  int            tolen
	);
	sendto函数:
		作用:向目标发送数据报
		本质:send函数将我们的数据复制黏贴进行系统的协议发送缓冲区,计算机伺机发出去
	参数1:当前客户端的socket(自己的socket)
	参数2:给接收方发送的字节串  UDP统一字节数 548
	参数3:参数2的大小(字节个数 548)
	参数4:填0
	参数5:对方IP地址与端口号结构体
	参数6:参数5的大小

	*/
	// 声明sendto函数中参数5所需的 服务端地址与端口号结构体
	struct sockaddr_in sockServer;
	// 给服务端地址与端口号结构体成员赋值
	sockServer.sin_family = AF_INET;
	sockServer.sin_port = htons(12345);
	sockServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	// 循环与客户端进行收发消息
	while (1)
	{
		// 定义要发送的字节数组
		char strBuf[548] = { 0 };
		// 手动发送
		scanf_s("%s", strBuf, 548);
		// 设置输入0时,将关闭客户端
		if ('0' == strBuf[0])
		{
			break;
		}

		// 1.发消息
		int nSet = sendto(sock, strBuf, sizeof(strBuf), 0, (struct sockaddr*)&sockServer, sizeof(sockServer));
		// 判断是否成功发送消息
		if (SOCKET_ERROR == nSet)
		{
			// 出错了
			int a = WSAGetLastError();
			printf("发送消息失败,获取的错误码为:%d\n", a);
			continue;
		}

		// 2.收消息
		// 定义recvfrom 函数所需的接收字节数组
		char buf[548] = { 0 };
		// 声明recvfrom函数中参数5所需的 结构体相应的IP地址与端口号
		struct sockaddr sockClient;	// 对方的IP地址与端口号
		// 定义recvfrom函数中参数6所需的 参数5结构体的大小
		int len = sizeof(sockClient);
		int nRet = recvfrom(sock, buf, 548, 0, &sockClient, &len);
		// 判断是否成功接收消息
		if (SOCKET_ERROR == nRet)
		{
			// 出错了
			int a = WSAGetLastError();
			printf("接收消息失败,获取的错误码为:%d\n", a);
			continue;
		}
		// 进行接收消息
		printf("Server say: %s\n", buf);	
	}
}

程序运行结果:

 

 

毕设案例|保安公司智慧管理系统的建设与开发方案 "保安公司智慧管理系统是一款专为保安行业设计的高效信息化解决方案,其核心功能涵盖了从人力资源管理到业务运营的各个方面。系统以Java作为开发语言,结合SpringMVC框架,确保了稳定性和可扩展性,而MySQL数据库则提供了强大的数据存储和处理能力。首先,系统允许用户设置各类保安,如门卫、巡逻员等,实现精细化分类管理。其次,保安信息管理模块包括详细的人事档案、资格证书、培训记录等,便于人员追踪和考核。部门和城市设置方便公司层级管理和异地项目管理。岗位设置与时间安排精确到分钟,确保排班科学合理。 阅读详情

相关推荐

openwrt编译及第一个安装包教程

Date: 2017.03.14 Made:SuperDeverloper Email: na1206@live.com Target: For mt7688 based board说明:本人在学习过程中走了不少弯路,希望本文档能为后来者提供便利。欢迎复制和使用本文档。本文档记录了搭建openwrt编译环境以及快速创建ipk包(openwrt上的安装程序)。本文档在实际应用中做过几次修改,以帮

SuperDevloper的博客 1万+

事件选择模型

    事件选择(WSAEventSelect)模型是另一个有用的异步 I/O 模型。和 WSAAsyncSelect 模型类似的是,它也允许应用程序在一个或多个套接字上,接收以事件为基 础的网络事件通知,最主要的差别在于网络事件会投递至一个事件对象句柄,而非投递到一个窗口例程。     事件通知模型要求我们的应用程序针对使用的每一个套接字,首先创建一个事件对象。创建方法是调用 WSACrea...

weixin_34342207的博客 316

用树莓派Pico低成本更新USB-C PD控制器固件实战指南

固件更新是嵌入式系统开发与维护中的核心环节,它直接决定了硬件设备的功能、性能与兼容性。其原理通常是通过特定的通信接口(如SWD、JTAG、UART或USB)与设备内部的Bootloader建立连接,将新的程序代码安全写入非易失性存储器。在USB Power Delivery(PD)和Type-C生态中,固件更新技术尤为重要,它能修复协议握手Bug、适配新设备并提升供电策略的灵活性。本文聚焦于一个典型的工程实践场景:如何利用广泛普及且成本极低的树莓派Pico开发板,作为USB-C协议到I²C协议的转换桥,实现

weixin_27869497的博客 461

Windows网络编程~TCP/IP~select(四)

1、select模型特点: 解决基本模型中accept以及recv阻塞的问题 实现多个客户端连接,与多个客户端分别通信 用于服务器 2、应用范围: 小用户访问量 3、select模型流程 打开网络库 校验版本 创建socket 绑定地址与端口 开始监听 调用select函数 4、select函数调用逻辑 本质 1、将客户端及服务器的socket装进数组里 2、通过select函数遍历数组,当某个socket有相应时,select通过参数/返回值发出反馈 3、如果是服务器socket,调用accep

yazjy1的博客 695

最新首发——boss直聘爬虫

本文介绍了使用Python开发Boss直聘爬虫的核心思路和技术要点。通过模拟浏览器访问搜索页面获取Cookie,然后构建API请求获取职位数据。关键步骤包括:1)使用DrissionPage库初始化浏览器;2)模拟用户浏览行为获取必要参数;3)设置完整的请求头信息;4)通过POST请求获取JSON格式的职位数据。文章提供了详细的代码实现,包括浏览器模拟、API请求构建、数据处理等核心功能模块,并强调了最新版接口改为POST访问的特点。该爬虫可自动翻页采集数据并保存为Excel文件,适用于安全实习等职位信息的

2301_79735033的博客 3320

MAPPO实战:从理论到代码的协作智能体训练指南

本文详细介绍了MAPPO算法在多智能体协作训练中的实战应用,从理论基础到代码实现全面解析。通过对比PPO与MAPPO的差异,深入讲解CTDE框架、网络架构设计、参数调优等关键环节,并提供实际项目中的调参经验和常见问题解决方案,帮助开发者快速掌握这一强化学习前沿技术。

weixin_42561040的博客 266

WSACreateEvent(),WSAEventSelect,WSAWaitForMultipleEvents(),WSAEnumNetworkEvents()

WSACreateEvent() 简述:创建一个新的事件对象。          #include           WSAEVENT WSAAPI WSACreateEvent( VOID );返回值:  如果函数成功,则返回值即是事件对象的句柄。  如果函数失败,返回WSA_INVALID_EVENT。应用程序可通过调用WSAGetLastError()函数获取进一步的错误信息。    

浓浓的巧克力 5393

spring-ai 1.0.0 学习(四)——提示词管理

摘要:本文介绍Spring AI中提示词管理的最佳实践。首先展示基础样例,指出直接传递用户输入的局限性。随后分析优质提示词应包含系统消息、上下文信息、输出结构和问答样例四要素。文章详述两种实现方式:链式调用(使用ChatClient构建器)和传统对象创建方法。进阶部分涵盖核心接口(Prompt、Message等)、消息类型、模板渲染配置(支持自定义)及提示词工程技巧(如RAG、任务分解)。最后提及高级功能如少样本模板和提示词库。全文强调结构化提示词对提升AI输出质量的关键作用,并展示Spring AI的灵活

hzp的专栏 1365

套接字I/O模型:WSAEventSelect网络模型(异步IO模型:事件选择模型)

而异步指的是操作系统帮我们完成检测数据到来的任务,程序不用管这个过程,也就不浪费程序自身的时间片做事,当我们接收到有信号的时候,直接去recv就可以了)大概意思是说,WSAEnumNetworkEvents复制出套接字中的网络事件记录(存放到WSANETWORKEVENTS结构体中),并且自动的清理掉相应套接字的网络事件信息,并且reset(重置)绑定的事件对象,防止下次发生网络事件的时候该网络事件是set(有信号)的状态。select网络模型是I/O复用模型,占用的是程序自身的时间片。

zxf347085420的博客 679

基于KiCad的STM32最小系统设计实战案例(含PCB布线)

手把手带你用KiCad完成STM32最小系统设计,涵盖原理图绘制、封装匹配、规则约束设置及关键信号PCB布线技巧;全程基于开源EDA工具KiCad,强调实操细节与常见坑点规避。

weixin_42452483的博客 360

西电微机系统课程设计步进电机开环控制系统

** 微机系统与应用课程设计 课题二 步进电机开环控制系统设计** 一、程设计目的 掌握微机系统总线与各芯片管脚连接方法,提高接口扩展硬件电路的连接能力。 加深对 A/D 和并行接口芯片的工作方式和编程方法的理解。 搞懂步进电机的工作原理及控制方式,掌握开环控制系统的设计思路和实现方法。 二、课程设计的内容 手动调节电位器旋钮(0V~5V),通过 ADC0809 模拟输入水库水位 0 米~50...

qq_37015775的博客 4038

基于FPGA的万兆以太网UDP/IP协议栈讲解

31bit,这种传输次序为big endian(大端对齐)。TCP/IP所有二进制整数在网络中传输时都要求采用这种次序,因此这种传输次序又称为网络字节序。版本(Version)+首部长度(IHL):长度为1字节。版本[0:3]就是IPv4或者IPv6,一般选择IPv4,即版本值为4。首部长度[4:7]是指首部有多少个32位数,因为4位的最大值为15,因此首部最长为60字节,5表示固定最小值为20字节。选项部分(可选字段)的最大值为40字节,不够4的倍数要用0填充,使数据部分的起始地址为4的倍数。...

ltqdxl的博客 1万+

MATPOWER下载安装教程

将MATPOWER文件复制在C:\Program Files (x86)\MATLAB\R2016b\bin目录下。原来的窗口中多了很多文件路径,点击【保存】,再点击【关闭】选择所要添加的MATPOWER文件夹,点击【选择文件夹】二、将MATPOWER放在bin目录下。找到菜单栏的【设置路径】点击【添加并包含子文件】一、从官网下载后解压。

weixin_47365903的博客 2万+

UDP/IP传输协议

一、传输层最重要的协议就是TCP和UDP。TCP协议复杂,是面向连接的传输协议且传输可靠;而UDP协议简单,是面向无连接的传输协议,传输速度快但传输不可靠。可以将UDP协议看作IP协议暴露在传输层的一个接口。 UDP协议同样以数据报(datagram)的方式进行数据传输,而且UDP协议提出了端口(port)的概念。IP协议进行的是IP地址到IP地址的传输。但是每台计算机有多个通信通道,并将多个通...

大不列颠小小咸鱼 1万+

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

UDP/IP select模型

select模型服务端代码: UDP/IP: UDP/IP协议的C/S模型不存在傻等的问题,而select模型只是能让recvfrom更灵活一些 select 代码逻辑: 1.所有的socket装进一个集合FD_SET UDP只有一个socket即将服务端的socket装进集合中就可以了 2.通过select函数,检测中的socket集合中...

m0_60178310的博客 768

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

深入浅出理解SOME/IP

SOME/IP,全称为Scalable service-Oriented MiddlewarE over IP,是用于控制消息的汽车中间件解决方案,是一种面向服务的可伸缩的协议。SOME/IP于2011年由BMW设计,2014年纳入AUTOSAR规范。 SOME/IP的报文格式如下图所示,由消息头部(Header)和消息体(Payload)组成,Header主要包括以下字段: Message ID,用于唯一标识消息,当消息为Method类型时,由Service ID和Method ID组成,当消

usstmiracle的博客 2万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SOME/IP协议详解[2 SOME/IP通信机制]

本章探讨车载ECU需要按照何种规则来实现数据的传输,因此熟悉这部分内容将对车载以太网SOME/IP的开发与测试至关重要。

hammershr2012的博客 9612

TCP/UDP/IP报文大小

不同的抓包程序和设备驱动程序所处的优先层次可能不同,抓包程序的优先级可能比设备驱动程序更高,也就是说,我们的抓包程序可能在设备驱动程序还没有填充不到64字节的帧的时候,抓包程序已经捕获了数据。中的概念,需要在 网卡中设置 的,如果IP层有一个数据报要传,而且数据的长度比链路层的MTU还大,那么IP层就需要进行分片(fragmentation),把数据报分成若干片,这样每一片都小于MTU。MTU值越大,封包就越大,理论上可增加传送速率,但 MTU值又不能设得太大,因为封包太大,传送时出现错误的机会大增。

路星辞*的博客 2546

UDP/IP与TCP/IP协议

1.现在的网络系统的两大基本架构B/S,C/S结构。也就是所谓的浏览器(Brower)/服务器端(Server),和客户端(Client)/服务端(Server)无论是B/S,还是C/S结构,最基本的用户交互都需要数据传输。B/S结构的应用层现在是使用的HTTP协议,也就是超文本传输协议。由于这一优点,服务器厂商不用关心浏览器的开发,只需要专注服务端。C/S结构需要厂商开发客户端和服务端,可以不遵...

YG爱木木 7118

基于UDP/IP协议的光口通信

1.1.1基于UDP/IP协议的光口通信基于之前在《8.5.3 基于UDP/IP协议的电口通信》中所介绍的 UDP IP 协议栈, 将其与Xilinx提供的 IP 核 1G/2.5G Et...

OpenFPGA的博客 2177

MAC、IP地址、TCP、UDP、SSL、OSI模型

掌握网络基础,是玩转 ESP8266 的起点。本文用通俗类比讲清 MAC 与 IP 的本质差异,对比 TCP、UDP、SSL 的应用场景,并图解 OSI 七层模型,帮你打牢物联网开发的“通信地基”。下一步,我们将从理论走向实战,真正动手做项目。

2301_81650162的博客 1396

TCP/UDP/IP分片

我们知道,当应用层程序之间进行网络数据传输时,在发送端,数据会从应用层沿着协议栈向下传输,通过TCP/IP层,然后经由链路层发送出去,而在接收 端,则是相反的顺序,数据经由链路层接收,然后沿着协议栈向上传输,通过IP/TCP层,最后由应用层程序进行读取。     而在IP层往链路层传输数据的时候,往往会做一个分片的操作,对于大多数链路层来讲,它都有一个最大传输单元(MTU),表示能够发

3591

RTPS协议之PSM:UDP/IP

RTPS协议都会给内置的entities定义entity IDs。PIM 指定参与者的 EntityId_t 有预定义的值 ENTITYID_PARTICIPANT。所有预定义的实体 ID 对应的 PSM 映射出现在下表中 - 由 RTPS 协议完全预定义的 EntityId_t 值中。在这个主版本(2)中,这些实体 ID 的含义不会改变,但是未来的次要版本可能会增加额外的保留实体 ID。

u010378559的博客 1716

UDP/IP 异步选择模型

实现步骤: 异步选择模型是基于Windows消息机制的,也就是消息队列,Windows操作系统会为每个窗口创建一个消息队列并且维护 1. 创建窗口: 创建窗口步骤: 第一步:创建窗口结构体: typedef struct tagWNDCLASSEXW { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int ...

m0_60178310的博客 242

UDP/IP 基本C/S模型

UDP/IP 与 TCP/IP的区别: TCP/IP协议的特点: 面向连接的,可靠的,基于字节流的传输层协议。 UDP/IP协议的特点: 面向非连接的,不可靠的,基于数据报的传输层协议。 基本C/S模型 TCP/IP 服务端与客户端是 1对1关系;UDP/IP 服务端与客户端 可以是1对1,1对多 关系。 基本C/S模型中服务端代码: UDP/IP: 是面向非连接的,所以不进行listen、a...

m0_60178310的博客 338

IP、TCP、UDP首部详解

一、IP首部: 1、第一个4字节(也就是第一行): (1)版本号(Version),4位;用于标识IP协议版本,IPv4是0100,IPv6是0110,也就是二进制的4和6。 (2)首部长度(Internet Header Length),4位;用于标识首部的长度,单位为4字节,所以首部长度最大值为:(2^4 - 1) * 4 = 60字节,但一般只推荐使用20字节的固定长度。

Leeon的博客 3万+
上一篇: UDP/IP select模型
下一篇: 二叉树遍历
xundao_803817
博客等级 码龄5年 7粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值