SOCKET模型之重叠I/O

从零构建个人知识库:Obsidian与Git实践打造可生长的第二大脑 在信息爆炸的时代,如何有效管理个人知识资产,构建一个可检索、可关联、可生长的个人知识库,成为提升学习效率和创造力的关键。其核心原理在于通过系统化的信息架构与工作流设计,将碎片化信息转化为结构化的知识网络。从技术价值看,这不仅是笔记方法的升级,更是个人知识管理(PKM)和思维模式的革新,能有效对抗信息过载与知识孤岛。实践中,以Obsidian为代表的本地Markdown笔记软件,结合双向链接和关系图谱功能,为知识网络的构建提供了强大支撑;而引入Git进行版本控制,则确保了知识资产的历史可追溯性与安全备份。这种 阅读详情

转载之:http://blog.sina.com.cn/s/blog_540e3fbb0100neln.html

(本文假设你已经具备用SOCKET简单模型编程的能力,如果对SOCKET一无所知请关注本系列其他文章)

目录:

1. 重叠模型的优点

2. 重叠模型的基本原理

3. 关于重叠模型的基础知识

4. 重叠模型的实现步骤

5. 多客户端情况的注意事项

一. 重叠模型的优点

1. 可以运行在支持Winsock2的所有Windows平台 ,而不像完成端口只是支持NT系统。

2. 比起阻塞、select、WSAAsyncSelect以及WSAEventSelect等模型,重叠I/O(Overlapped I/O)模型使应用程序能达到更佳的系统性能。

因为它和这4种模型不同的是,使用重叠模型的应用程序通知缓冲区收发系统直接使用数据,也就是说,如果应用程序投递了一个10KB大小的缓冲区来接收数据,且数据已经到达套接字,则该数据将直接被拷贝到投递的缓冲区。

而这4种模型种,数据到达并拷贝到单套接字接收缓冲区中,此时应用程序会被告知可以读入的容量。当应用程序调用接收函数之后,数据才从单套接字缓冲区拷贝到应用程序的缓冲区,差别就体现出来了。

3. 从《windows网络编程》中提供的试验结果中可以看到,在使用了P4 1.7G Xero处理器(CPU很强啊)以及768MB的回应服务器中,最大可以处理4万多个SOCKET连接,在处理1万2千个连接的时候CPU占用率才40% 左右 ―― 非常好的性能,已经直逼完成端口了^_^

二. 重叠模型的基本原理

说了这么多的好处,你一定也跃跃欲试了吧,不过我们还是要先提一下重叠模型的基本原理。

概括一点说,重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个Winsock I/O请求。针对这些提交的请求,在它们完成之后,应用程序会收到通知,于是就可以通过自己另外的代码来处理这些数据了。

需要注意的是,有两个方法可以用来管理重叠IO请求的完成情况(就是说接到重叠操作完成的通知):

1. 事件对象通知(event object notification)

2. 完成例程(completion routines) ,注意,这里并不是完成端口

而本文只是讲述如何来使用事件通知的的方法实现重叠IO模型,完成例程的方法准备放到下一篇讲 :) (内容太多了,一篇写不完啊) ,如没有特殊说明,本文的重叠模型默认就是指的基于事件通知的重叠模型。

既然是基于事件通知,就要求将Windows事件对象与WSAOVERLAPPED结构关联在一起(WSAOVERLAPPED结构中专门有对应的参数),通俗一点讲,就是。。。。对了,忘了说了,既然要使用重叠结构,我们常用的send, sendto, recv, recvfrom也都要被WSASend, WSASendto, WSARecv, WSARecvFrom替换掉了, 它们的用法我后面会讲到,这里只需要注意一点,它们的参数中都有一个Overlapped参数,我们可以假设是把我们的WSARecv这样的操作操作“绑定”到这个重叠结构上,提交一个请求,其他的事情就交给重叠结构去操心,而其中重叠结构又要与Windows的事件对象“绑定”在一起,这样我们调用完WSARecv以后就可以“坐享其成”,等到重叠操作完成以后,自然会有与之对应的事件来通知我们操作完成,然后我们就可以来根据重叠操作的结果取得我们想要德数据了。

也许说了半天你还是不大明白,那就继续往后面看吧。。。。。。。-_-b,语言表达能力有限啊~~~

三. 关于重叠模型的基础知识

下面来介绍并举例说明一下编写重叠模型的程序中将会使用到的几个关键函数。

1. WSAOVERLAPPED结构

这个结构自然是重叠模型里的核心,它是这么定义的

typedef struct _WSAOVERLAPPED{
DWORDInternal;
DWORDInternalHigh;
DWORD Offset;
DWORDOffsetHigh;
WSAEVENT hEvent; // 唯一需要关注的参数,用来关联WSAEvent对象
} WSAOVERLAPPED, *LPWSAOVERLAPPED;
我们需要把WSARecv等操作投递到一个重叠结构上,而我们又需要一个与重叠结构“绑定”在一起的事件对象来通知我们操作的完成,看到了和hEvent参数,不用我说你们也该知道如何来来把事件对象绑定到重叠结构上吧?大致如下:
WSAEVENT event; // 定义事件
WSAOVERLAPPED AcceptOverlapped ; // 定义重叠结构
event = WSACreateEvent(); // 建立一个事件对象句柄
ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED)); // 初始化重叠结构
AcceptOverlapped.hEvent = event; // Done !!
 

2. WSARecv系列函数

在重叠模型中,接收数据就要靠它了,它的参数也比recv要多,因为要用刀重叠结构嘛,它是这样定义的:

intWSARecv(
SOCKETs, // 当然是投递这个操作的套接字
LPWSABUFlpBuffers, // 接收缓冲区,与Recv函数不同
// 这里需要一个由WSABUF结构构成的数组
DWORDdwBufferCount, // 数组中WSABUF结构的数量
LPDWORDlpNumberOfBytesRecvd, // 如果接收操作立即完成,这里会返回函数调用
// 所接收到的字节数
LPDWORDlpFlags, // 说来话长了,我们这里设置为0 即可
LPWSAOVERLAPPEDlpOverlapped, // “绑定”的重叠结构
LPWSAOVERLAPPED_COMPLETION_ROUTINElpCompletionRoutine
// 完成例程中将会用到的参数,我们这里设置为 NULL
);
返回值:
WSA_IO_PENDING : 最常见的返回值,这是说明我们的WSARecv操作成功了,但是
I/O操作还没有完成,所以我们就需要绑定一个事件来通知我们操作何时完成
 
举个例子:(变量的定义顺序和上面的说明的顺序是对应的,下同)
SOCKET s;
WSABUF DataBuf; // 定义WSABUF结构的缓冲区
// 初始化一下DataBuf
#define DATA_BUFSIZE 5096
char buffer[DATA_BUFSIZE];
ZeroMemory(buffer, DATA_BUFSIZE);
DataBuf.len = DATA_BUFSIZE;
DataBuf.buf = buffer;
DWORD dwBufferCount = 1, dwRecvBytes = 0, Flags = 0;
// 建立需要的重叠结构
WSAOVERLAPPED AcceptOverlapped ;// 如果要处理多个操作,这里当然需要一个
// WSAOVERLAPPED数组
WSAEVENT event; // 如果要多个事件,这里当然也需要一个WSAEVENT数组
// 需要注意的是可能一个SOCKET同时会有一个以上的重叠请求,
// 也就会对应一个以上的WSAEVENT
Event = WSACreateEvent();
ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED));
AcceptOverlapped.hEvent = event; // 关键的一步,把事件句柄“绑定”到重叠结构上
// 作了这么多工作,终于可以使用WSARecv来把我们的请求投递到重叠结构上了,呼。。。。
WSARecv(s, &DataBuf, dwBufferCount, &dwRecvBytes,
&Flags, &AcceptOverlapped, NULL);
其他的函数我这里就不一一介绍了,因为我们毕竟还有MSDN这么个好帮手,而且在讲后面的完成例程和完成端口的时候我还会讲到一些 ^_^
 

3. WSAWaitForMultipleEvents函数

熟悉WSAEventSelect模型的朋友对这个函数肯定不会陌生,不对,其实大家都不应该陌生,这个函数与线程中常用的WaitForMultipleObjects函数有些地方还是比较像的,因为都是在等待某个事件的触发嘛。

因为我们需要事件来通知我们重叠操作的完成,所以自然需要这个等待事件的函数与之配套。

DWORDWSAWaitForMultipleEvents(
DWORDcEvents, // 等候事件的总数量
const WSAEVENT*lphEvents, // 事件数组的指针
BOOLfWaitAll, // 这个要多说两句:
// 如果设置为 TRUE,则事件数组中所有事件被传信的时候函数才会返回
// FALSE则任何一个事件被传信函数都要返回
// 我们这里肯定是要设置为FALSE的
DWORDdwTimeout, // 超时时间,如果超时,函数会返回 WSA_WAIT_TIMEOUT
// 如果设置为0,函数会立即返回
// 如果设置为 WSA_INFINITE只有在某一个事件被传信后才会返回
// 在这里不建议设置为WSA_INFINITE,因为。。。后面再讲吧..-_-b
BOOLfAlertable // 在完成例程中会用到这个参数,这里我们先设置为FALSE
);
返回值:
WSA_WAIT_TIMEOUT :最常见的返回值,我们需要做的就是继续Wait
WSA_WAIT_FAILED : 出现了错误,请检查cEvents和lphEvents两个参数是否有效
如果事件数组中有某一个事件被传信了,函数会返回这个事件的索引值,但是这个索引值需要减去预定义值 WSA_WAIT_EVENT_0才是这个事件在事件数组中的位置。
具体的例子就先不在这里举了,后面还会讲到
注意:WSAWaitForMultipleEvents函数只能支持由WSA_MAXIMUM_WAIT_EVENTS对象定义的一个最大值,是 64,就是说WSAWaitForMultipleEvents只能等待64个事件,如果想同时等待多于64个事件,就要 创建额外的工作者线程,就不得不去管理一个线程池,这一点就不如下一篇要讲到的完成例程模型了。

4. WSAGetOverlappedResult函数

既然我们可以通过WSAWaitForMultipleEvents函数来得到重叠操作完成的通知,那么我们自然也需要一个函数来查询一下重叠操作的结果,定义如下

BOOL WSAGetOverlappedResult(
SOCKET s, // SOCKET,不用说了
LPWSAOVERLAPPED lpOverlapped, // 这里是我们想要查询结果的那个重叠结构的指针
LPDWORD lpcbTransfer, // 本次重叠操作的实际接收(或发送)的字节数
BOOL fWait, // 设置为TRUE,除非重叠操作完成,否则函数不会返回
// 设置FALSE,而且操作仍处于挂起状态,那么函数就会返回FALSE
// 错误为WSA_IO_INCOMPLETE
// 不过因为我们是等待事件传信来通知我们操作完成,所以我们这里设
// 置成什么都没有作用…..-_-b 别仍鸡蛋啊,我也想说得清楚一些…
LPDWORD lpdwFlags // 指向DWORD的指针,负责接收结果标志
);
这个函数没什么难的,这里我们也不需要去关注它的返回值,直接把参数填好调用就可以了,这里就先不举例了
唯一需要注意一下的就是如果WSAGetOverlappedResult完成以后,第三个参数返回是 0 ,则说明通信对方已经关闭连接,我们这边的SOCKET

四。实现重叠模型的步骤

作了这么多的准备工作,费了这么多的笔墨,我们终于可以开始着手编码了。其实慢慢的你就会明白,要想透析重叠结构的内部原理也许是要费点功夫,但是只是学会如何来使用它,却是真的不难,唯一需要理清思路的地方就是和大量的客户端交互的情况下,我们得到事件通知以后,如何得知是哪一个重叠操作完成了,继而知道究竟该对哪一个套接字进行处理,应该去哪个缓冲区中的取得数据,everything will be OK^_^。

下面我们配合代码,来一步步的讲解如何亲手完成一个重叠模型。

【第一步】定义变量…………

#define DATA_BUFSIZE 4096 // 接收缓冲区大小
SOCKET ListenSocket, // 监听套接字
AcceptSocket; // 与客户端通信的套接字
WSAOVERLAPPED AcceptOverlapped; // 重叠结构一个
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
// 用来通知重叠操作完成的事件句柄数组
WSABUF DataBuf[DATA_BUFSIZE] ;
DWORD dwEventTotal = 0, // 程序中事件的总数
dwRecvBytes = 0, // 接收到的字符长度
Flags = 0; // WSARecv的参数
 

【第二步】创建一个套接字,开始在指定的端口上监听连接请求

和其他的SOCKET初始化全无二致,直接照搬即可,在此也不多费唇舌了,需要注意的是为了一目了然,我去掉了错误处理,平常可不要这样啊,尽管这里出错的几率比较小。

WSADATA wsaData;
WSAStartup(MAKEWORD(2,2),&wsaData);
 
ListenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //创建TCP套接字
 
SOCKADDR_IN ServerAddr; //分配端口及协议族并绑定
ServerAddr.sin_family=AF_INET;
ServerAddr.sin_addr.S_un.S_addr =htonl(INADDR_ANY);
ServerAddr.sin_port=htons(11111);
 
bind(ListenSocket,(LPSOCKADDR)&ServerAddr, sizeof(ServerAddr)); // 绑定套接字
 
listen(ListenSocket, 5); //开始监听

【第三步】接受一个入站的连接请求

一个accept就完了,都是一样一样一样一样的啊~~~~~~~~~~

至于AcceptEx的使用,在完成端口中我会讲到,这里就先不一次灌输这么多了,不消化啊^_^

AcceptSocket = accept (ListenSocket, NULL,NULL) ;

当然,这里是我偷懒,如果想要获得连入客户端的信息(记得论坛上也常有人问到),accept的后两个参数就不要用NULL,而是这样

SOCKADDR_IN ClientAddr; // 定义一个客户端得地址结构作为参数
int addr_length=sizeof(ClientAddr);
AcceptSocket = accept(ListenSocket,(SOCKADDR*)&ClientAddr, &addr_length);
// 于是乎,我们就可以轻松得知连入客户端的信息了
LPCTSTR lpIP = inet_ntoa(ClientAddr.sin_addr); // IP
UINT nPort = ClientAddr.sin_port; // Port

【第四步】建立并初始化重叠结构

为连入的这个套接字新建立一个WSAOVERLAPPED重叠结构,并且象前面讲到的那样,为这个重叠结构从事件句柄数组里挑出一个空闲的对象句柄“绑定”上去。

// 创建一个事件
// dwEventTotal可以暂时先作为Event数组的索引
EventArray[dwEventTotal] = WSACreateEvent();
 
ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED)); // 置零
AcceptOverlapped.hEvent = EventArray[dwEventTotal]; // 关联事件
 
char buffer[DATA_BUFSIZE];
ZeroMemory(buffer, DATA_BUFSIZE);
DataBuf.len = DATA_BUFSIZE;
DataBuf.buf = buffer; // 初始化一个WSABUF结构
dwEventTotal ++; // 总数加一

【第五步】以WSAOVERLAPPED结构为参数,在套接字上投递WSARecv请求

各个变量都已经初始化OK以后,我们就可以开始Socket操作了,然后让WSAOVERLAPPED结构来替我们管理I/O 请求,我们只用等待事件的触发就OK了。

if(WSARecv(AcceptSocket ,&DataBuf,1,&dwRecvBytes,&Flags,
& AcceptOverlapped, NULL) == SOCKET_ERROR)
{
// 返回WSA_IO_PENDING是正常情况,表示IO操作正在进行,不能立即完成
// 如果不是WSA_IO_PENDING错误,就大事不好了~~~~~~!!!
if(WSAGetLastError() != WSA_IO_PENDING)
{
// 那就只能关闭大吉了
closesocket(AcceptSocket);
WSACloseEvent(EventArray[dwEventTotal]);
}
}

【第六步】用WSAWaitForMultipleEvents函数等待重叠操作返回的结果

我们前面已经给WSARecv关联的重叠结构赋了一个事件对象句柄,所以我们这里要等待事件对象的触发与之配合,而且需要根据WSAWaitForMultipleEvents函数的返回值来确定究竟事件数组中的哪一个事件被触发了,这个函数的用法及返回值请参考前面的基础知识部分。

DWORD dwIndex;
// 等候重叠I/O调用结束
// 因为我们把事件和Overlapped绑定在一起,重叠操作完成后我们会接到事件通知
dwIndex = WSAWaitForMultipleEvents(dwEventTotal,
EventArray ,FALSE ,WSA_INFINITE,FALSE);
// 注意这里返回的Index并非是事件在数组里的Index,而是需要减去WSA_WAIT_EVENT_0
dwIndex = dwIndex – WSA_WAIT_EVENT_0;

【第七步】使用WSAResetEvent函数重设当前这个用完的事件对象

事件已经被触发了之后,它对于我们来说已经没有利用价值了,所以要将它重置一下留待下一次使用,很简单,就一步,连返回值都不用考虑

WSAResetEvent(EventArray[dwIndex]);

【第八步】使用WSAGetOverlappedResult函数取得重叠调用的返回状态

这是我们最关心的事情,费了那么大劲投递的这个重叠操作究竟是个什么结果呢?其实对于本模型来说,唯一需要检查一下的就是对方的Socket连接是否已经关闭了

DWORD dwBytesTransferred;
WSAGetOverlappedResult( AcceptSocket, AcceptOverlapped ,
&dwBytesTransferred, FALSE, &Flags);
// 先检查通信对方是否已经关闭连接
// 如果==0则表示连接已经,则关闭套接字
if(dwBytesTransferred == 0)
{
closesocket(AcceptSocket);
WSACloseEvent(EventArray[dwIndex]); // 关闭事件
return;
}

【第九步】“享受”接收到的数据

如果程序执行到了这里,那么就说明一切正常,WSABUF结构里面就存有我们WSARecv来的数据了,终于到了尽情享用成果的时候了!喝杯茶,休息一下吧~~~^_^

DataBuf.buf就是一个char*字符串指针,听凭你的处理吧,我就不多说了

【第十步】同第五步一样,在套接字上继续投递WSARecv请求,重复步骤 6 ~ 9

这样一路作下来,我们终于可以从客户端接收到数据了,但是回想起来,呀~~~~~,这样岂不是只能收到一次数据,然后程序不就Over了?…….-_-b 所以我们接下来不得不重复一遍第四步和第五步的工作,再次在这个套接字上投递另一个WSARecv请求,并且使整个过程循环起来,are u clear??

大家可以参考我的代码,在这里就先不写了,因为各位都一定比我smart,领悟了关键所在以后,稍作思考就可以灵活变通了。

五。多客户端情况的注意事项

完成了上面的循环以后,重叠模型就已经基本上搭建好了80%了,为什么不是100%呢?因为仔细一回想起来,呀~~~~~~~,这样岂不是只能连接一个客户端??是的,如果只处理一个客户端,那重叠模型就半点优势也没有了,我们正是要使用重叠模型来处理多个客户端。

所以我们不得不再对结构作一些改动。

1. 首先,肯定是需要一个SOCKET数组 ,分别用来和每一个SOCKET通信

其次,因为重叠模型中每一个SOCKET操作都是要“绑定”一个重叠结构的,所以需要为每一个SOCKET操作搭配一个WSAOVERLAPPED结构,但是这样说并不严格,因为如果每一个SOCKET同时只有一个操作,比如WSARecv,那么一个SOCKET就可以对应一个WSAOVERLAPPED结构,但是如果一个SOCKET上会有WSARecv 和WSASend两个操作,那么一个SOCKET肯定就要对应两个WSAOVERLAPPED结构,所以有多少个SOCKET操作就会有多少个WSAOVERLAPPED结构。

然后,同样是为每一个WSAOVERLAPPED结构都要搭配一个WSAEVENT事件,所以说有多少个SOCKET操作就应该有多少个WSAOVERLAPPED结构,有多少个WSAOVERLAPPED结构就应该有多少个WSAEVENT事件,最好把SOCKET – WSAOVERLAPPED – WSAEVENT三者的关联起来,到了关键时刻才会临危不乱:)

2. 不得不分作两个线程:

一个用来循环监听端口,接收请求的连接,然后给在这个套接字上配合一个WSAOVERLAPPED结构投递第一个WSARecv请求,然后进入第二个线程中等待操作完成。

第二个线程用来不停的对WSAEVENT数组WSAWaitForMultipleEvents,等待任何一个重叠操作的完成,然后根据返回的索引值进行处理,处理完毕以后再继续投递另一个WSARecv请求。

这里需要注意一点的是,前面我是把WSAWaitForMultipleEvents函数的参数设置为WSA_

INFINITE的,但是在多客户端的时候这样就不OK了,需要设定一个超时时间,如果等待超时了再重新WSAWaitForMultipleEvents,因为WSAWaitForMultipleEvents函数在没有触发的时候是阻塞在那里的,我们可以设想一下,这时如果监听线程忠接入了新的连接,自然也会为这个连接增加一个Event,但是WSAWaitForMultipleEvents还是阻塞在那里就不会处理这个新连接的Event了。也不知道说明白了没有。。。。。。-_-b 可能在这里你也体会不到,真正编码的时候就会明白了。

其他还有不明白的地方可以参考我的代码,代码里也有比较详尽的注释, Enjoy~~~

不过可惜是为了照顾大多数人,使用的是MFC的代码,显得代码有些杂乱。

六.已知问题

这个已知问题是说我的代码中的已知问题,可不是重叠结构的已知问题:)

这个示例代码已经写好了很久了,这两天做最后测试的时候才发现竟然有两个Bug,而且还不是每次都会出现,5555,我最近是实在没有精力去改了,如果有心的朋友能修改掉这两个Bug,那真是造福大家了,这篇文章都险些流产,我更没有经历去修改都快要淡忘了的代码的Bug了,我写在这里提醒一下大家了,反正这个代码也仅仅是抛砖引玉而已,而且我觉得比起代码来还是文字比较珍贵^_^,因为重叠模型的代码网上也还是有不少的。两个Bug是这样的:

1. 多个客户端在连续退出的时候,有时会出现异常;

2. 有时多个客户端的接收缓冲区竟然会重叠到一起,就是说A客户端发送的数据后面会根有B客户端上次发来的数据。。。。。-_-b

改进算法:其实代码中的算法还有很多可以改进的地方,limin朋友就向我提及过几个非常好的改进算法,比如如何在socket数组中寻找空闲的socket用来通信,但是我并没有加到这份代码里面来,因为本来重叠模型的代码就比较杂,再加上这些东西恐怕反而会给初学者带来困难。但是非常欢迎各位和我讨论重叠模型的改进算法以及我代码中存在问题!^_^

微信小程序 - {errCode: 10008, errno: 1500104, errMsg: “writeBLECharacteristicValue:fail write characteris 微信小程序errCode: 10008, errno: 1500104, errMsg: "writeBLECharacteristicValue:fail write characteristics error. 10008, errMsg=The value's length is invalid.",uni-app微信小程序报错,uniApp小程序调用蓝牙api报错,向低功耗蓝牙设备的某个特征写入数据时错误,UniApp微信小程序蓝牙API调用报错10008解决方案,蓝牙设备进行通信时,向设备写入数据 阅读详情

相关推荐

记录LeNet的硬件加速器设计(一)

LeNet的硬件加速器设计实现。

2301_81029398的博客 3543

【整理】重叠IO模型的编程思路及C++源代码

编程步骤 1、创建一个套接字,开始在指定的端口上监听连接请求。 2、接收一个入站的连接请求。 3、为接受的套接字创建新的WSAOVERLAPPED结构,并分配事件对象句柄。 4、以WSAOVERLAPPED结构为参数,在套接字上投递WSARecv调用。 5、将所有接受套接字的事件组建事件数组,并调用WSAWaitForMultipleEvents函数,等待与重叠调用关联在一起的事件受信。

brk1985的专栏 1209

从翼型到湍流:用生活化案例图解空气动力学核心概念(中英双语版)

本文通过飞机机翼、F1赛车、高尔夫球等生活化案例,图解空气动力学核心概念。深入浅出地解释了攻角如何产生升力、边界层与流动分离如何影响阻力、马赫数如何划分速度世界,以及涡流与湍流的特性与应用。文章还介绍了计算流体动力学(CFD)这一现代数字风洞工具,帮助读者直观理解这些塑造现代交通与运动设计的无形之力。

metaverse5vr的博客 475

重叠IO之完成例程

重叠IO事件通知与完成例程的区别: 重叠IO事件通知:需要调用 WSAGetOverlappedResult,获取等到事件的结果,然后根据逻辑,进行分类处理; 重叠IO完成例程:主要是通过处理WSARecv函数的回调函数,和处理WSASend函数的回调函数,不用进行循环去获取等待事件的结果,系统会自动调用回调函数进行处理,完成例程的性能更好 回调函数: void CALLBACK CompletionROUTINE( IN DWORD dwError, // 错

m0_60178310的博客 613

毕设别再硬肝了:我用 GPT + Codex 做项目、写论文,效率直接起飞

这个也是神器。你项目做完之后,最怕的是老师一问就懵。这时候你直接把你的项目发给它,让它模拟老师提问。这是我的毕业设计题目和项目简介,请你站在答辩老师角度,提出20个高频问题,并给出简洁好背的回答。要求:问题尽量贴近计算机专业本科毕业答辩。为什么选这个题目?技术选型为什么这样定?你的创新点是什么?系统难点是什么?数据库怎么设计的?你的模型为什么选这个?如果继续优化,下一步怎么做?这个对答辩真的帮助很大。说实话,如果没有 GPT + Codex,

m0_74100417的博客 1846

STM32H743 SD卡读写避坑实录:CubeMX配置MDMA给FATFS,我的FreeRTOS项目踩了哪些雷?

本文详细解析了STM32H743在CubeMX配置中结合SDMMC、MDMA与FATFS的实战避坑指南,特别针对FreeRTOS环境下的SD卡读写问题提供了解决方案。从时钟配置到FATFS参数设置,再到DMA缓存维护和FreeRTOS集成技巧,帮助开发者高效解决数据损坏、DMA传输错误等常见问题,提升项目稳定性。

weixin_30878501的博客 494

C++ Windows Socket五种I/O模型之重叠IO模型(二)

前面一节我们简单的介绍了事件通知的重叠IO模型,有兴趣的可以点击 C++ Windows Socket五种I/O模型之重叠IO模型(一)查看一下,这一章主要是介绍一下完成例程模型。 基本原理 完成例程在投递一个请求之后如(WSARecv)之后,系统完成之后不再以事件通知你,而是在完成之后自动调用你提供的LPWSAOVERLAPPED_COMPLETION_ROUTINE 类型的的回调函数来处理消息。 WSARecv 在重叠模型中,接收数据就要靠它了,它的参数也比recv要多,和事件通知重叠唯一不同的是最后一

weixin_45317033的博客 1199

保姆级教程:用YOLOv5s训练PCB缺陷检测模型(附北大公开数据集)

本文提供了一份基于YOLOv5s的PCB缺陷检测模型从零开始的完整实战教程。详细解析了如何使用北大公开数据集,涵盖环境搭建、数据处理、模型训练、性能评估及优化部署全流程,并针对工业场景中常见的类别不均衡问题给出了具体解决方案,旨在帮助开发者快速构建高精度的自动化质检系统。

weixin_28285943的博客 306

c++重叠I/0

#include  #include  #include   #include  using namespace std;  #pragma comment(lib,"Ws2_32.lib")  #pragma comment (lib, "mswsock.lib")  const int nPort=10000;  const int buf_len=1024;  //对于同一个客户连接套接字,

wodexiaobaitu的专栏 1202

【Bug已解决】Claude Desktop Cowork 报错 Workspace unavailable 解决方案

方案适用场景推荐指数确认虚拟机镜像下载完整性排查的第一步,最基础的前提检查⭐⭐⭐⭐⭐确认虚拟机平台功能已启用Windows 系统功能层面的必要条件⭐⭐⭐⭐⭐重启 CoworkVMService快速尝试恢复服务正常状态⭐⭐⭐⭐完全重启客户端排除临时性状态错乱⭐⭐⭐⭐降级使用文件工具临时替代方案,不阻塞当前工作⭐⭐⭐报错的本质是Cowork 功能依赖的虚拟机管理服务,在 Windows 应用包隔离机制下未能正确定位虚拟机文件的实际存放路径。

博客 6227

COSMO-RS理论:流体相热力学预测的核心模型与技术突破

摘要:COSMO-RS模型通过量子化学计算分子表面电荷分布,实现了从微观量子尺度到宏观化工过程的热力学预测。该模型基于介电连续介质理论,将分子表面片段化处理,通过σ-剖面描述电荷分布,并计算片段间的静电失配能和氢键能。其核心算法通过自洽化学势方程求解活度系数,克服了传统模型依赖实验参数的局限。随着技术进步,模型引入了高阶描述符和色散力修正,提升了预测精度。在药物研发、化工分离等领域广泛应用,但仍存在对长程有序结构预测不足等局限性。该模型为复杂体系的热力学性质预测提供了重要理论工具。

ASKCOS博客 973

学习笔记(08):C++网络编程进阶-IO模型之重叠Overlapped IO(基于完成例程)

C/S模型在企业级的软件开发中非常常见,高并发网络通讯更是很多项目的核心模块,学好socket 网络编程显得尤为重要,本课程分为TCP/IP 协议、socket基础与进阶的异步通讯模型三个部分,通过浅显易懂的代码与讲解,让你的C++网络编程能力得到质的飞跃,具备开发高并发服务器的能力!...

weixin_38793855的博客 535

uniapp - 如何跟内嵌 web-view 组件内的网页交互,与 web-view 内嵌网页进行双向通信(uniapp 与 webview 网页之间的 “相互“ 传值)提供详细的示例代码及解决方案

uni-app如何实现在H5环境中与web-view中的网页交互通讯uniappuni-app 与 web-view内嵌网页 双向通信 如何跟内嵌web-view交互uniappAPP与webview子页面交互uniappAPP与webview子页面交互关于uni-app 使用 web-view 页面之间互相跳转、通信等问题uniapp的web-view嵌入网页,网页与uniapp通信webview如何与uniapp写的H5页面交互嵌套webview调用uniapp各种API组件实现H5和app通讯和交互

✅ 精选推荐文章 1万+

SOCKET之重叠I/O模型

首先要想再套接字上使用重叠I/O模型,首先必须使用WSA_FLAG_OVERLAPPED 这个标志创建套接字WSASocket(AF_INET,SOCKET_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);如果创建套接字的时候使用socket 而不是WSASocket函数那默认会设者WSA_FLAG_OVERLAPPED标志随后将一个WSAOVERLAPPED

vbanglev的小窝^_^ 2642

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Socket模型之重叠I/O模型

Socket模型之重叠I/O模型 这几天一直在看关于Socket编程的几种异步编程,我觉得关于重叠I/O模型的一些基本知识,我有必要记下来。 首先,我觉得重叠模型的有点就是允许应用程序使用重叠数据结构一次投递一个或多个异步I/O请求,当提交的请求完成之后,与之关联的重叠数据结构中关联的事件对象就会受信,然后应用程序就可以通过WSAWaitForMultipleEvents函数来判...

MengDeMao1234的博客 309

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Socket编程模型之重叠IO(Overlapped I/O)模型

转载请注明来源:http://blog.youkuaiyun.com/caoshiying/article/details/52876090 一、原理 Winsock2的发布使得Socket I/O有了和文件I/O统一的接口。我们可以通过使用Win32文件操纵函数ReadFile和WriteFi...

cheqiane9431的博客 537

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

手把手教你玩转SOCKET模型之 重叠I/O 篇

转载自小猪的手把手教你玩转SOCKET模型之 重叠I/O 篇                                                            前   言   其实我首先应该道歉,因为7月份的时候曾信誓旦旦的说要写一套关于SOCKET所有模型的入门文章以及配套代码,不过没想到后天竟然被美女所迷出去度假了,刚刚回来不久。。。。。。-_-b其实那些模型的配套代码我已

木头人专栏 1496

C++ Windows Socket五种I/O模型之重叠IO模型(一)

重叠模型的基本原理 简单来说,重叠模型就是让应用程序使用重叠数据结构WSAOVERLAPPED,次投递一个或多个Winsock I/O请求。针对这些提交的请求,在它们完成之后,应用程序会收到通知,于是就可以通过自己另外的代码来处理这些数据了。 需要注意的是,有两个方法可以用来管理重叠IO请求的完成情况(就是说接到重叠操作完成的通知): 1. 事件对象通知(event object notification) 2. 完成例程(completion routines) ,注意,这里并不是完成端口 本篇文章主要讲

weixin_45317033的博客 1314

手把手教你玩转SOCKET模型之重叠I/O篇(上)

手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                                              

小猪的网络编程 5万+

手把手教你玩转SOCKET模型之重叠I/O篇(上)

手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                          

asdfasdfsadf 597

socket 五种模型理解之三---------重叠I/O模型(1.事件通知形式)

关键函数 int WSARecv( SOCKET s, // 当然是投递这个操作的套接字 LPWSABUF lpBuffers, // 接收缓冲区,与Recv函数不同 // 这里需要一个由WSABUF结构构成的数组 DWORD dwBufferCount, // 数组中WSABUF结构的数量 LPDWORD lpNumberOfBytesRecvd, // 如果接收操作立即

有梦,有追求 2063

手把手教你玩转SOCKET模型之重叠I/O篇

  手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                                            

hzhxxx的专栏 1403

转:变手把手教你玩转SOCKET模型之重叠I/O篇

手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。” ...

aolan7349的博客 220

Socket I/O模型之重叠I/O(overlapped I/O)

Winsock2的发布使得Socket I/O有了和文件I/O统一的接口。我们可以通过使用Win32文件操纵函数ReadFile和WriteFile来进行Socket I/O。伴随而来的,用于普通文件I/O的重叠I/O模型和完成端口模型对Socket I/O也适用了。这些模型的优点是可以达到更佳的系统性能,但是实现较为复杂,里面涉及较多的C语言技巧。例如我们在完成端口模型中会经常用到所谓的“尾随数

xidianhunhun的专栏 403
上一篇: 深度探索I/O完成端口
下一篇: Java Unicode简介
sdudubing
博客等级 码龄16年 117粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值