int select(

int nfds,            //忽略

fd_ser* readfds,    //指向一个套接字集合,用来检测其可读性

fd_set* writefds,   // 指向一个套接字结合,用来检测其可写性

fd_ser* exceptfds, //指向一个套接字集合,用来检测错误

const struct timeval * timeout   //指定此函数等待的最长时间,如果为NULL,则最长时间为无限大。

);

参数说明:

(1)   nfds  windows下未使用,linux下会使用此参数

(2)   readfds:   readfds集合中的套接字发送在以下三种情况中任意一种就会被视为可读,select函数返回后继续留在readfds集合中,不可读的会被移除readfds集合。

1.套接字有数据可读,可以对套接字调用recv函数接收数据

2.套接字的连接已经关闭,重启或者中断,此时应该对套接字进行关闭

3.listen被调用,并且有一个连接未决,对 listen套接字调用accept函数建立新的链接。

(3)   writefds:    readfds集合中的套接字在以下三种情况下会被视为可写

1.使用connect套接字首次建立链接

2.使用accept套接字被接收

3.使用send操作失败,返回WSAEWOULDBLOCK错误,而且缓冲区的空间变得可用

send出去的数据其实都先存在winsock的发送缓冲区中,然后才发送出去,如果缓冲区满了,那么再调用send(WSASend,sendto,WSASendTo)的话,就会返回一个 WSAEWOULDBLOCK的错误码,接下来随着发送缓冲区中的数据被发送出去,缓冲区中出现可用空间时,一个 FD_WRITE 事件才会被触发,这里比较容易混淆的是 FD_WRITE 触发的前提是 缓冲区要先被充满然后随着数据的发送又出现可用空间,而不是缓冲区中有可用空间

(4)   exceptfds   (未使用过,没有进行深入的研究)

1.如果一个非阻塞连接调用正在被处理,连接视图失败

2.OOB数据可读

(5)   timeout:   设置时间,如果超过设定时间,还没有网络事件发生,则返回0,如果此参数为NULL,select会无限等待,直到有一个描述字满足条件。

timeout指向一个timeval结构

typedef struct timeval

{

long tv_sec;       //只是等待多少秒

long tv_usec;     //指示等待多少毫秒

} timeval;

如果timeval为{0,0},则select()立即返回,这可用于探询所

选套接口的状态。如果处于这种状态,则select()调用可认为是非阻塞的,且一切适用于非阻塞调用的假设都适用于它

具体编程流程

1.初始化套接字集合fdSocket,向这个集合添加监听套接字

2.将fdSocket集合拷贝到fdRead传递给select函数,当有时间发送时,select函数移除fdRead集合中没有未决io操作的套接字

3.比较原来fdSocket集合与select处理后的fdRead集合。确定哪些套接字有未决IO

4.回到第2步继续处理

my_socket();

my_bind(port);

my_listen();

//PostMessage(h_hand,WM_USER_THREADEND,0,0);

//select模型处理过程

//(1).初始化套接字集合fdSocket.添加监听套接字句柄到这个集合

FD_ZERO(&fdSocket);

FD_SET(sSock,&fdSocket);

while (1)

{

//(2.)将fdSocket集合的一个拷贝fdRead传递给select函数

//当有时间发生时,select函数一处fdRead集合中没有未决IO操作的套接字句柄,然后返回。

fd_set fdRead = fdSocket;

int nRet = select(0,&fdRead,NULL,NULL,NULL); //timeout参数控制select()完成的时间。若timeout参数为空指针,则select()将一直阻塞

//到有一个描述字满足条件。否则的话,timeout指向一个timeval结构,其中指定了select()

//调用在返回前等待多长时间

//fdwrite 1. 接成功的套接字 在第一次建立连接时,C/S端都会触发一个FD_WRITE事件

//2, 触发的前提是 缓冲区要先被充满然后随着数据的发送又出现可用空间

if(nRet>0)

{

//(3)通过原来的fdSocket集合与select处理后的fdRead集合比较

//确定哪些套接字有未决io,并进一步处理这些io

for(int i=0;i

{

if(FD_ISSET(fdSocket.fd_array[i],&fdRead))

{

if(fdSocket.fd_array[i] == sSock) //(1)监听套接字收到新连接,有新的链接

{

if(fdSocket.fd_count

{

int socke_len = sizeof(remoteAddr);

//4.accept

SOCKET cSock = accept(sSock,(SOCKADDR*)&remoteAddr,&socke_len);

if(cSock == INVALID_SOCKET)

{

AfxMessageBox("accept failed!\n");

printf("accept failed!\n");

continue;

}

FD_SET(cSock,&fdSocket);

//printf("接收到一个连接请求!:%s\r\n",inet_ntoa(remoteAddr.sin_addr) );

//printf("当前连接到服务器的客户端有 %d 个\n",fdSocket.fd_count+1);

socket_id = cSock*(-1);

PostMessage(h_hand,WM_USER_THREADEND,0,0);

}

else

{

AfxMessageBox("too much connections !\n");

printf("too much connections \n");

continue;

}

}

else

{

int nRecv = recv(fdSocket.fd_array[i],readText,sizeof(readText),0);

socket_id = fdSocket.fd_array[i];

if(nRecv>0) //(2)可读

{

readText[nRecv] = '\0';

//HWND g_WindowHandle=((CDialog *)AfxGetMainWnd())->GetSafeHwnd();

PostMessage(h_hand,WM_USER_THREADEND,0,0);

}

else //(3)连接关闭,重启或中断

{

closesocket(fdSocket.fd_array[i]);

FD_CLR(fdSocket.fd_array[i],&fdSocket);

someone_out = TRUE;

PostMessage(h_hand,WM_USER_THREADEND,0,0);

}

}

}

}

}

else

{

AfxMessageBox("failed select()]n");

printf("failed select()]n");

break;

}

}

以上只是我在项目中使用的部分代码,最开始的my_socket,my_bind,my_listen都是自己对socket,bind,listen自己重新做的封装

java socket编程 select_windows socket编程select模型使用相关推荐

  1. socket编程(二) select 模型

    select 模型是winsock中最常见的I/O模型,主要是它能够防止程序在套接字处于阻塞模式的时候经过一次I/O操作后被阻塞,同时也能够防止套接字处于非阻塞模式产生的WSAEWOULDBLOCK错 ...

  2. SOCKET学习第三阶段(SELECT模型)

    /* 2009-11-18 20:57:05 AUTHOR:BY.Feng */ SELECT套接字模型的学习 Winsock提供了五种类型的套接字I/O 模型,可让Winsock应用程序 对I/O ...

  3. 糖儿飞教你学C++ Socket网络编程——28. 使用select模型实现一对多通信

    在项目10中,采用多线程技术实现了TCP协议的一对多通信,但如果客户端过多,就会导致服务器端的线程数量膨胀,使得服务器的资源占用过大.能不能让TCP程序在一个线程中同时与多个客户端进行通信呢?答案是可 ...

  4. socket select模型

    由于socket recv()方法是堵塞式的,当多个客户端连接服务器时,其中一个socket的recv调用时,会产生堵塞,使其他连接不能继续. 如果想改变这种一直等下去的焦急状态,可以多线程来实现(不 ...

  5. socket编程的select模型

    在掌握了socket相关的一些函数后,套接字编程还是比较简单的,日常工作中碰到很多的问题就是客户端/服务器模型中,如何让服务端在同一时间高效的处理多个客户端的连接,我们的处理办法可能会是在服务端不停的 ...

  6. connect: 网络不可达_Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制

    本文转自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...

  7. Java之初步识别网络编程:IP、端口号、TCP/UDP、Socket、URL等

    文章目录 一.网络编程概述 二.网络通信要素概述 三.通信要素1:IP和端口号 IP相关 InetAdress类 如何实例化InetAddress 端口号 四.通信要素2:网络协议 TCP/IP协议簇 ...

  8. 浅谈JAVA中如何利用socket进行网络编程(二)

    转自:http://developer.51cto.com/art/201106/268386.htm Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以 ...

  9. Linux下网络socket编程——实现服务器(select)与多个客户端通信

    一.关于socket通信 服务器端工作流程: 调用 socket() 函数创建套接字 用 bind() 函数将创建的套接字与服务端IP地址绑定 调用listen()函数监听socket() 函数创建的 ...

最新文章

  1. jQuery Ajax 实例 全解析(转)
  2. c语言字母输出什么意思,C语言中字符的输入输出以及计算字符个数的方法详解...
  3. MongoDB最简单的入门教程之三 使用Java代码往MongoDB里插入数据
  4. 我如何在20小时内为AWS ML专业课程做好准备并进行破解
  5. python代码性能分析_Python 性能分析入门指南
  6. Vue2.0三——Vue-router
  7. 【短语学习】out of the box的含义和翻译
  8. CMake编译protobuf
  9. OpenCV图像处理(7)——图像上写TEXT
  10. ImportError: DLL load failed: 找不到指定的模块。
  11. 【渝粤教育】国家开放大学2018年春季 7408-21T多媒体软件制作与使用 参考试题
  12. 发送HTTP请求返回415状态码的解决办法
  13. 软件选择,iDreamPiano、freepiano、EveryonePiano
  14. 全志A31S(android 4.2/4.4)截屏
  15. MSDC 4.3 接口规范(5)
  16. 内存卡在电脑显示要格式化
  17. 如何在安卓手机上编辑Excel表格?
  18. 爬虫案例 --- Python 爬取淘宝数据存到数据库
  19. C语言 入门到精通100题
  20. OnMeasure()

热门文章

  1. 机器学习误差分析(Error Analysis)实战
  2. Linux环境高级编程函数,Linux环境高级编程--出错处理(CLStatus)
  3. mysql 提交_MySQL 事务提交过程
  4. 抓图软件_Faststone capture8.3
  5. 实验七:层叠样式表(二)
  6. PLSQL Developer 12 注册码
  7. java 汉字 数字_java数字转汉字工具类详解
  8. php 存储型跨站,php云人才系统存储型跨站两处
  9. python json数据的文件读写操作
  10. 多视角图像生成--Multi-View Image Generation from a Single-View