阻塞式的Socket很容易理解,但是使用起来非常别扭。Windows提供了选择(Select)I/O模型,进行异步Socket通信.

Select模型

int select(_In_    int    nfds,//忽略. 此参数为了与Berkeley sockets兼容._Inout_ fd_set *readfds,//检查可读性fd_set指针._Inout_ fd_set *writefds,//检查可写性fd_set指针._Inout_ fd_set *exceptfds,//检查错误fd_set指针_In_    const struct timeval *timeout//超时
);

本函数用于确定一个或多个套接口的状态。对每一个套接口,调用者可查询它的可读性、可写性及错误状态信息。用fd_set结构来表示一组等待检查的套接口。在调用返回时,这个结构存有满足一定条件的套接口组的子集,并且select()返回满足条件的套接口的数目。

下面是代码:

#include <Winsock2.h>
#include <stdio.h>
#include <process.h>static const int PORT = 7777;
static const int BUFFER_LENGTH = 128 ;static int  g_TotalConn = 0 ;
static SOCKET g_ClientSocket[FD_SETSIZE] ;unsigned int __stdcall WorerkThread(void *);
bool InitWSA() ;int main()
{if(!InitWSA()){return -1 ;}SOCKET sockListen = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP) ;SOCKADDR_IN addrSrv ;addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK) ;addrSrv.sin_family = AF_INET ;addrSrv.sin_port = htons(PORT) ;bind (sockListen, (SOCKADDR *)&addrSrv, sizeof(SOCKADDR)) ;listen (sockListen, 3) ;_beginthreadex(NULL, 0, WorerkThread, NULL, 0, NULL) ;SOCKADDR_IN addrClient ;int len = sizeof (addrClient) ;while (true){SOCKET client = accept(sockListen, (SOCKADDR *)&addrClient, &len) ;g_ClientSocket[g_TotalConn++] = client ;}closesocket(sockListen) ;WSACleanup () ;return 0 ;
}unsigned int __stdcall WorerkThread(void *)
{printf("线程begin:\n") ;int            i;fd_set         fdread;fd_set         fdwrite;int            ret;struct timeval tv = {1, 0};char           szMessage[BUFFER_LENGTH];while (true){FD_ZERO(&fdread);FD_ZERO(&fdwrite);for (i = 0; i < g_TotalConn; i++){FD_SET(g_ClientSocket[i], &fdread) ;FD_SET(g_ClientSocket[i], &fdwrite) ;}ret = select(0, &fdread, &fdwrite, NULL, &tv);/*if(g_TotalConn > 0 && ret == SOCKET_ERROR){printf("Socket:an error occurred!\n") ;}*/if (ret == 0){printf("超时\n") ;continue ;}for (i = 0; i < g_TotalConn; i++){if (FD_ISSET(g_ClientSocket[i], &fdread)){ret = recv(g_ClientSocket[i], szMessage, BUFFER_LENGTH, 0);if (ret == 0 || (ret == SOCKET_ERROR && WSAGetLastError() == WSAECONNRESET)){printf("Client socket %d closed.\n", i);closesocket(g_ClientSocket[i]);g_ClientSocket[i] = 0 ;if(i != g_TotalConn -1){g_ClientSocket[i--] = g_ClientSocket[g_TotalConn -1] ;}g_TotalConn-- ;}else{szMessage[ret] = '\0';send(g_ClientSocket[i], szMessage, strlen(szMessage), 0);printf("发送数据给Client:%s\n", szMessage) ; }}if (FD_ISSET(g_ClientSocket[i], &fdwrite)){//可以发送数据}}}printf("线程end:\n") ;return 0 ;
}bool InitWSA()
{WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 2, 2 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) {                                 return false ;}if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 ) {WSACleanup();return false ; }return true ;
}

特点:
1、程序可能阻塞在select处一段指定的时间。
2、使用轮循的方式,检测Socket是否可读或可写、效率低下。

点评:虽然实现了异步IO,但是实现方式“扭曲”,效率低下,不推荐使用,尤其是服务端。

Windows网络编程之(二)Socket通信非阻塞模式Select(TCP和UDP)相关推荐

  1. 非阻塞式编程 php,简单介绍PHP非阻塞模式

    非阻塞模式是指利用socket事件的消息机制,Server端与Client端之间的通信处于异步状态. 让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断 ...

  2. Linux 下socket通信终极指南(附TCP、UDP完整代码)

    linux下用socket通信,有TCP.UDP两种协议,网上的很多教程把两个混在了一起,或者只讲其中一种.现在我把自己这两天研究的成果汇总下来,写了一个完整的,适合初学者参考,也方便自己以后查阅. ...

  3. js监听select值变化_网络编程——C++实现socket通信(TCP)高并发之select模式

    相关函数: 服务端: socket() bind() listen() FD_ZERO()等辅助函数 select() 高并发select模式 accept() read() 或 recv()等 wr ...

  4. 网络编程(基于socket接口技术的进程间通信)接上一篇文章补充

    目录 一.网络编程(基于socket接口技术) 1.基于TCP协议的网络通信 编程模型: 2.基于UDP通信协议的网络通信 编程模型: 3.新增函数: 大小端数据转换函数: ip地址转换函数: TCP ...

  5. UE4 Socket多线程非阻塞通信【2】

    昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心 紧接着第一部分,别说话,勿打断我游离的思绪我们走我们走... 二.消息结构&收发队列 先不急着往下走,先捋一捋,不知道自己要干什么地走下去是一件 ...

  6. UE4 Socket多线程非阻塞通信【1】

    昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心 前面写了一篇有关于虚幻4加载第三方库的博客思前顾后,感觉细节还是有必要拎起来注意下. ue4自带的Fsocket用起来依旧不是那么的顺手,感觉超出了我的 ...

  7. socket的阻塞模式和非阻塞模式(send和recv函数在阻塞和非阻塞模式下的表现)

    socket的阻塞模式和非阻塞模式 无论是Windows还是Linux,默认创建socket都是阻塞模式的 在Linux中,可以再创建socket是直接将它设置为非阻塞模式 int socket (i ...

  8. java socket 阻塞模式_(四) 如何将socket设置为非阻塞模式

    1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket(    _In_ int af,   ...

  9. socket阻塞和非阻塞模式

    socket阻塞和非阻塞模式 本文讨论Linux下的socket套接字 一.同步.异步阻塞和非阻塞 同步:主动请求并等待IO操作完成的方式 异步:主动请求数据后,可以去处理其它任务,随后等待IO操作完 ...

  10. 《Windows网络编程案例教程》-董相志 学习记录 阻塞/非阻塞套接字编程

    <Windows网络编程案例教程>-董相志 学习记录 阻塞/非阻塞套接字编程 2.3 阻塞/非阻塞套接字编程 阻塞套接字编程通信流程图 2.3.1 阻塞套接字客户机编程 1.启动并初始化W ...

最新文章

  1. Oracle Exadata 简介
  2. R语言广义线性模型函数GLM、(Model fit and regression diagnostics)、模型充分性评估方法、使用plot函数以及car包函数
  3. LeetCode 215. Kth Largest Element in an Array--数字第K大的元素--最大堆或优先队列--C++,Python解法
  4. Tapestry IoC Decorator
  5. python 数据分析学什么-如何在业余时学数据分析?
  6. jvm在不同系统中的最大内存空间地址
  7. oracle 数据库的数据事务的相关概念
  8. 4加密问题漏洞修复_Apache Shiro 反序列化漏洞实战
  9. 《C++ Primer Plus》16.2 智能指针模板类
  10. Java-GuardedBlocks与BusyWaitting忙等待
  11. java jackson_Jackson 框架的高阶应用
  12. 封装判断一个字符的后缀名和前缀的方法
  13. JS中clientHeight、scrollHeight、offsetHeight、scrollTop、offsetTop的定义
  14. 新基建促进智能化基础设施管控平台的搭建
  15. 大数据scala面试题汇总
  16. 绩效/加薪/年终奖,虐你如初恋
  17. Python------2022-1-11作业
  18. Word表格外的第一个空行如何删除
  19. 【沐风老师】3dMax Gyroid Minimal Surface 极小曲面建模详细教程
  20. error writing messa ge: File too large

热门文章

  1. educoder软件工程导论结构化分析方法
  2. windows10安装AWVS
  3. 闫啸的发明和发现20220901
  4. html生成一维码,一维码条形码生成工具
  5. kafka权威指南-笔记
  6. i2c-tools 使用集锦
  7. Java8 实战系列-05-lambda 类型推断
  8. PMP题库重要吗?什么样的题库才是好的题库?
  9. css 设置浏览器最小宽度
  10. 最新软件外包公司排名-中国IT人力外包公司排名