1.WSAEventSelect()çè¿åå¼ï¼
2.WSAEventSelect()简述
3.服务器端编程心得(六)—— 关于网络编程的源码一些实用技巧和细节
4.WSAEventSelect()返回值
WSAEventSelect()çè¿åå¼ï¼
å¦æåºç¨ç¨åºæå®çç½ç»äºä»¶åå ¶ç¸åºçäºä»¶å¯¹è±¡æå设置ï¼åè¿å0ãå¦åçè¯ï¼å°è¿åSOCKET_ERRORé误ï¼åºç¨ç¨åºå¯éè¿WSAGetLastError()æ¥è·åç¸åºçé误代ç ãå¨ä½¿ç¨select()åWSAAsyncSelect()å½æ°æ¶ï¼WSAEventSelect()常ç¨æ¥å³å®ä½æ¶è¿è¡æ°æ®ä¼ éæä½ï¼å¦send()ærecv()ï¼ï¼å¹¶ææè½ç«å³æåãä½æ¯ä¸ä¸ªç¨³å®çåºç¨ç¨åºåºè¯¥å好è¿æ ·çåå¤ï¼å³äºä»¶å¯¹è±¡è¢«è®¾ç½®ï¼å¹¶ä¸ä¸ä¸ªWinSockè°ç¨ä»¥WSAEWOULDBLOCKç«å³è¿å ã举ä¾æ¥è¯´ï¼æå¯è½åçä¸è¿°æä½åºåï¼
(i) å¥æ¥å£sä¸å°è¾¾æ°æ®ï¼WinSock设置äºWSAEventSelectäºä»¶å¯¹è±¡ã
(ii) åºç¨ç¨åºè¿è¡å ¶ä»æä½ã
(iii) å¨è¿è¡æä½æ¶ï¼åºç¨ç¨åºè°ç¨äºioctlsocket(s, FIONREAD...)并åç°ææ°æ®å¯è¯»ã
(iv) åºç¨ç¨åºè°ç¨ä¸ä¸ªrecv(s,...)æ¥è¯»åæ°æ®ã
(v) æååºç¨ç¨åºçå¾ WSAEventSelect()ææå®çæ°æ®å¯¹è±¡ï¼è¯¥æ°æ®å¯¹è±¡æåºæ°æ®å¯è¯»ã
(vi) åºç¨ç¨åºè°ç¨recv(s,...)ï¼ä½ä»¥WSAEWOULDBLOCKé误失败ã
å ¶ä»çæä½åºåä¹æ¯å¯è½çã
æåå°è®°å½äºç½ç»äºä»¶çåçï¼éè¿è®¾ç½®å é¨ç½ç»äºä»¶è®°å½çç¸åºä½ï¼ï¼å¹¶ä¸å°ç¸åºçäºä»¶å¯¹è±¡è®¾ç½®äºä¿¡å·åï¼ä¸ä¼å¯¹è¯¥ç½ç»äºä»¶ä½è¿ä¸æ¥çæä½ï¼ç´å°åºç¨ç¨åºè°ç¨äºç¸åºçå½æ°æ¾å¼å°éæ°å 许该ç½ç»äºä»¶åç¸åºäºä»¶å¯¹è±¡çä¿¡å·ã
ç½ç»äºä»¶ éæ°å 许å½æ°
FD_READ recv() æ recvfrom()
FD_WRITE send() æ sendto()
FD_OOB recv()
FD_ACCEPT accept() æWSAAccept()ï¼ç´å°è¿åçé误代ç 为 WSATRY_AGAINï¼æææ¡ä»¶å½æ°è¿åCF_DEFERã
FD_CONNECT NONE
FD_CLOSE NONE
FD_QOS ç¨SIO_GET_QOS å½ä»¤è°ç¨WSAIoctl()ã
FD_GROUP_QOS ç¨SIO_GET_GROUP_QOSå½ä»¤è°ç¨WSAIoctl()ã
é误代ç ï¼
WSANOTINITIALISED å¨è°ç¨æ¬APIä¹ååºæåè°ç¨WSAStartup()ã
WSAENETDOWN ç½ç»åç³»ç»å¤±æã
WSAEINVAL åæ°ä¸æéæ³å¼ï¼æè æå®çå¥æ¥å£å¤äºéæ³ç¶æã
WSAEINPROGRESS ä¸ä¸ªé»å¡çWinSockè°ç¨æ£å¨è¿è¡ä¸ï¼æè æå¡æä¾è ä»å¨å¤çä¸ä¸ªåè°å½æ°
WSAENOTSOCK æè¿°åä¸æ¯ä¸ä¸ªå¥æ¥å£ã
å¦è¯·åé ï¼WSACloseEvent() ,WSACreateEvent(),WSAEnumNetworkEvents(),WSAGetOverlappedResult(),WSAWaitForMultipleEvents().
WSAEventSelect()简述
在Windows Socket API中,WSAEventSelect()函数是源码一个关键的工具,用于管理和监控网络套接字的源码事件。它的源码主要任务是确定一个指定的套接字(s)与一组特定的网络事件(FD_READ、FD_CONNECT、源码FD_OOB等)之间的源码ios试玩平台源码关系,这些事件将通过一个事件对象(hEventObject)进行跟踪。源码
首先,源码参数's'是源码一个描述符,代表了要监控的源码网络套接字。这个套接字可能是源码连接的,监听的源码,或者正在进行数据传输的源码,具体取决于应用程序的源码需求。
hEventObject参数是源码一个句柄,它是幕聊源码一个事件对象,用于标识那些已设置的网络事件。当这些事件发生时,这个事件对象会触发相应的回调,通知应用程序进行相应的处理。
最后,'lNetworkEvents'是一个掩码,它是一个二进制位模式,用于指定应用程序想要监控的网络事件。例如,如果设置为FD_READ,函数将关注读取事件;如果设置为FD_CONNECT,表示关注连接事件。通过组合这些事件,应用程序可以灵活地定制对网络事件的响应策略。
总的物品领用源码来说,WSAEventSelect()函数是网络编程中一个不可或缺的函数,它使得程序能够高效地处理和响应各种网络事件,提高应用程序的响应性和效率。
服务器端编程心得(六)—— 关于网络编程的一些实用技巧和细节
接触了多种项目,编写了大量网络编程代码,涉及 Windows 和 Linux 平台,积累了不少经验与心得。本文将分享网络编程的实用技巧与细节,希望对读者有所助益。
非阻塞的 connect() 函数编写:在创建 socket 时将其设置为非阻塞模式,使用 connect() 进行连接。若能立即连接成功返回 0,否则返回 -1 或 EINPROGRESS。通过 select() 检测 socket 是否可写来判断连接状态。在 Windows 平台上,领用asp源码除了 select(),也可使用 WSAAsyncSelect 或 WSAEventSelect 来检测。
非阻塞 socket 下的收发数据:在 Linux 和 Windows 平台,先用 select()、WSAAsyncSelect() 或 epoll_wait 检测 socket 有无数据可读或可写。对于收发数据的代码,Linux epoll 的 ET 模式要求一次性收完所有数据;水平模式或 Windows 平台则可根据业务需求一次性收取固定大小数据或直至数据收完。设置超时时间,检测整个收发过程是否超时。
上层业务解析数据包:处理数据包前先收取固定大小的包头信息,根据包头中指定的包体大小收取包体。确保包完整后解析并传递给上层业务逻辑。注意连续接收到的数据包可能有不同组合方式,需循环处理直至完整数据包出现。
nagle 算法:开启此算法时,记忆解析源码小数据包可能不会立即发送,合并后一次性发送。若需实时性,可禁用此算法,以立即发送小数据包。Linux 默认开启,禁用方法为设置 noDelay 为 1。
select 函数参数问题:在 Linux 下,参数必须设置为所有 socket 描述符句柄中的最大值加 1;Windows 下兼容性考虑,参数可填任意值。
bind 函数绑定地址:使用 0.0.0.0 绑定任意网卡地址,使用 .0.0.1 绑定本地回环地址。前者允许从任意本地网卡连接,后者仅允许连接本地回环地址。
SO_REUSEADDR 和 SO_REUSEPORT:设置这两个选项,解决 socket 被系统回收后,短时间内无法重新绑定同一地址和端口的问题。Linux 实现更为严格,所有进程都受限,Windows 则允许本进程重复使用。
心跳包机制:通过定时发送心跳包维持连接正常。心跳包间隔时间可根据项目需求调整,确保连接状态检查与数据流量优化。客户端发送心跳包给服务器端,检测连接状态。
重连机制:在连接尝试失败后,设置递增的重试间隔时间。网络故障恢复时应立即尝试重连。Windows 下使用 IsNetworkAlive 检测网络状态变化。
EINTR 错误码处理:在 Linux 环境下,对于 network 函数检测 EINTR 错误码,表明函数因信号中断而未完成,应重新尝试或利用其他方式检查状态。
减少系统调用:优化高性能服务器程序时,尽量减少系统调用。例如,在主循环中缓存时间获取结果,避免重复调用系统函数。
忽略 SIGPIPE 信号:在 Linux 平台上,当侦听 socket 关闭后,对端发送数据会导致 SIGPIPE 信号。应忽略此信号,避免进程因异常终止。
CppGuide 学习资料:为 C/C++ 开发者准备的全面学习资源,涵盖语言基础、网络编程、操作系统原理、项目源码分析等,同时提供学习方法、推荐书籍、简历指导和求职技巧等内容。
WSAEventSelect()返回值
当应用程序成功设置指定的网络事件及其关联的事件对象后,WSAEventSelect()函数通常返回0,表示设置已成功。反之,如果出现错误,函数将返回INVALID_SOCKET错误,开发者可以通过WSAGetLastError()获取具体错误代码。 在使用select()和WSAAsyncSelect()的过程中,WSAEventSelect()用于决定何时执行数据传输操作,如send()或recv()。理想情况下,应用应预见可能遇到WSAEWOULDBLOCK立即返回的情况,比如当数据在套接口s上到达,WinSock已设置事件对象后,应用程序可能正在进行其他操作,如调用ioctlsocket(s, FIONREAD...)发现数据可读。 在这种情况下,应用程序会尝试recv(s,...)读取数据,但可能因WSAEWOULDBLOCK错误而失败。当网络事件被记录并设置信号后,应用程序通常不会立即处理,直到主动调用相应的函数重新启用网络事件和事件对象的信号。例如:FD_READ:recv() 或 recvfrom()重新启用
FD_WRITE:send() 或 sendto()重新启用
FD_OOB:recv()重新启用
FD_ACCEPT:accept() 或 WSAAccept(),直到错误代码为WSATRY_AGAIN,表明服务暂时不可用
FD_CONNECT:无需特别处理,等待连接完成
FD_CLOSE:无需处理,等待套接字关闭
FD_QOS和FD_GROUP_QOS:通过WSAIoctl()调用SIO_GET_QOS或SIO_GET_GROUP_QOS命令处理
务必注意,使用前务必确保WSAStartup()已成功初始化,否则会遇到WSANOTINITIALISED错误。其他可能遇到的错误包括:WSAENETDOWN(网络子系统失效)、WSAEINVAL(参数错误或套接字状态异常)、WSAEINPROGRESS(正在进行阻塞调用)和WSAENOTSOCK(描述字不是套接字)。 有关更多功能和用法,可以参考WSACloseEvent(), WSACreateEvent(), WSAEnumNetworkEvents(), WSAGetOverlappedResult(), 和 WSAWaitForMultipleEvents()的文档。