选择模型2
时间:2022-04-22
本文章向大家介绍选择模型2,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
选择模型
fd_set结构可以把多个套接字连在一起,形成一个套接字集合
typedef struct fd_set{
u_int fd_count;//下面数组的大小
SOCKET fd_array[FD_SETSIZE];//套接字句柄数组
}fd_set;
网络事件:
readfds集合:数据可读,连接关闭,重启或者中断
writefds集合:数据能发送
exceptfds集合:OOB数据可读
设置超时:
如果为null为无限阻塞,知道有网络事件发生
typedef struct timeval{
long tv_sec;//指示等待多少秒
long tv_usec;//指示等待多少毫秒
}timeval;
应用举例
1 初始化fdSocket集合,添加监听套接字句柄
2 将fdSocket集合拷贝fRead传递给select函数,当有事件发生的时候,select函数移除fRead中没有未决IO操作的句柄,然后返回
3 比较原来的fdSocket集合,与select处理过的fdRead集合,确定哪些套接字有未决IO并处理这些IO
4 回到2进行选择
1 CInitSock theSock;//初始化winsock库
2 int main()
3 {
4 USHORT nPort=4567;//此服务器监听的端口号
5 //创建监听套接字
6 SOCKET sListen=::listen(AF_INET,SOCK_STREAM,IPPROTO_TCP);
7 sockaddr_in sin;
8 sin.sin_family = AF_INET;
9 sin.sin_port = htons(nPort);
10 sin.sin_addr.S_un.S_addr = INADDR_ANY;
11 //绑定套接字到本地机器
12 if(::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)
13 {
14 printf("Failed bind()!n");
15 return 0;
16 }
17 //进入监听模式
18 ::listen(sListen,5);
19
20 //select模型处理过程
21 ////////////////////////////////////////////////////////////////////////////
22 // 1 初始化fdSocket集合,添加监听套接字句柄
23 fd_set fdSocket;//所有可用套接字集合
24 FD_ZERO(&fdSocket);
25 FD_SET(sListen,&fdSocket);
26 while(TRUE)
27 {
28 ////////////////////////////////////////////////////////////////////////
29 //2 将fdSocket集合拷贝fRead传递给select函数,当有事件发生的时候,select函数移除fRead中没有未决IO操作的句柄,然后返回
30 fd_set fdRead = fdSocket;
31 int nRet = ::select(0,&fdRead,NULL,NULL,NULL);
32 if(nRet>0)
33 {
34 ///////////////////////////////////////////////////////////////////
35 // 3 比较原来的fdSocket集合,与select处理过的fdRead集合,确定哪些套接字有未决IO并处理这些IO
36 for(int i=0;i<(int)fdSocket.fd_count;i++)
37 {
38 if(FD_ISSET(fdSocket.fd_array[i],&fdRead))
39 {
40 if(fdSocket.fd_array[i]==sListen)// 1 监听套接字连接新连接
41 {
42 sockaddr_in addrRemote;
43 int nAddrLen = sizeof(addrRemote);
44 SOCKET sNew = ::accept(sListen,(SOCKADDR*)&addrRemote,&nAddrLen);
45 FD_SET(sNew,&fdSocket);
46 printf("接收到连接(%s)n",::inet_ntoa(addrRemote.sin_addr));
47 }
48 else
49 {
50 printf("Too much connections!n");
51 continue;
52 }
53 }
54 else
55 {
56 char szText[256];
57 int nRecv = ::recv(fdSocket.fd_array[i],szText,strlen(szText),0);
58 if(nRecv > 0)//可读
59 {
60 szText[nRecv] = ' ';
61 printf("接收到数据:%sn",szText);
62 }
63 else//连接关闭或者重启
64 {
65 ::closesocket(fdSocket.fd_array[i]);
66 FD_CLR(fdSocket.fd_array[i],&fdSocket);
67 }
68 }
69 }
70 }
71 else
72 {
73 printf("Failed select()!n");
74 break;
75 }
76 }
77 return 0;
78 }
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android仿抖音上下滑动布局
- 一个简单的Android轨迹动画
- Android自定义圆环倒计时控件
- Android 使用URLConnection下载音频文件的方法
- Android自定义TimeButton实现倒计时按钮
- android自定义圆形倒计时显示控件
- android实现上下左右滑动界面布局
- Android使用MediaCodec将摄像头采集的视频编码为h264
- Android开发人脸识别登录功能
- Android利用碎片fragment实现底部标题栏(Github模板开源)
- Android MediaPlayer 播放音频的方式
- Android切圆角的几种常见方式总结
- Android DSelectorBryant 单选滚动选择器的实例代码
- Android 拍照选择图片并上传功能的实现思路(包含权限动态获取)
- Android Canvas的drawText()与文字居中方案详解