java socket编程 select_windows socket编程select模型使用
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模型使用相关推荐
- socket编程(二) select 模型
select 模型是winsock中最常见的I/O模型,主要是它能够防止程序在套接字处于阻塞模式的时候经过一次I/O操作后被阻塞,同时也能够防止套接字处于非阻塞模式产生的WSAEWOULDBLOCK错 ...
- SOCKET学习第三阶段(SELECT模型)
/* 2009-11-18 20:57:05 AUTHOR:BY.Feng */ SELECT套接字模型的学习 Winsock提供了五种类型的套接字I/O 模型,可让Winsock应用程序 对I/O ...
- 糖儿飞教你学C++ Socket网络编程——28. 使用select模型实现一对多通信
在项目10中,采用多线程技术实现了TCP协议的一对多通信,但如果客户端过多,就会导致服务器端的线程数量膨胀,使得服务器的资源占用过大.能不能让TCP程序在一个线程中同时与多个客户端进行通信呢?答案是可 ...
- socket select模型
由于socket recv()方法是堵塞式的,当多个客户端连接服务器时,其中一个socket的recv调用时,会产生堵塞,使其他连接不能继续. 如果想改变这种一直等下去的焦急状态,可以多线程来实现(不 ...
- socket编程的select模型
在掌握了socket相关的一些函数后,套接字编程还是比较简单的,日常工作中碰到很多的问题就是客户端/服务器模型中,如何让服务端在同一时间高效的处理多个客户端的连接,我们的处理办法可能会是在服务端不停的 ...
- connect: 网络不可达_Java网络编程和NIO详解1:JAVA 中原生的 socket 通信机制
本文转自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...
- Java之初步识别网络编程:IP、端口号、TCP/UDP、Socket、URL等
文章目录 一.网络编程概述 二.网络通信要素概述 三.通信要素1:IP和端口号 IP相关 InetAdress类 如何实例化InetAddress 端口号 四.通信要素2:网络协议 TCP/IP协议簇 ...
- 浅谈JAVA中如何利用socket进行网络编程(二)
转自:http://developer.51cto.com/art/201106/268386.htm Socket是网络上运行的两个程序间双向通讯的一端,它既可以接受请求,也可以发送请求,利用它可以 ...
- Linux下网络socket编程——实现服务器(select)与多个客户端通信
一.关于socket通信 服务器端工作流程: 调用 socket() 函数创建套接字 用 bind() 函数将创建的套接字与服务端IP地址绑定 调用listen()函数监听socket() 函数创建的 ...
最新文章
- jQuery Ajax 实例 全解析(转)
- c语言字母输出什么意思,C语言中字符的输入输出以及计算字符个数的方法详解...
- MongoDB最简单的入门教程之三 使用Java代码往MongoDB里插入数据
- 我如何在20小时内为AWS ML专业课程做好准备并进行破解
- python代码性能分析_Python 性能分析入门指南
- Vue2.0三——Vue-router
- 【短语学习】out of the box的含义和翻译
- CMake编译protobuf
- OpenCV图像处理(7)——图像上写TEXT
- ImportError: DLL load failed: 找不到指定的模块。
- 【渝粤教育】国家开放大学2018年春季 7408-21T多媒体软件制作与使用 参考试题
- 发送HTTP请求返回415状态码的解决办法
- 软件选择,iDreamPiano、freepiano、EveryonePiano
- 全志A31S(android 4.2/4.4)截屏
- MSDC 4.3 接口规范(5)
- 内存卡在电脑显示要格式化
- 如何在安卓手机上编辑Excel表格?
- 爬虫案例 --- Python 爬取淘宝数据存到数据库
- C语言 入门到精通100题
- OnMeasure()
热门文章
- 机器学习误差分析(Error Analysis)实战
- Linux环境高级编程函数,Linux环境高级编程--出错处理(CLStatus)
- mysql 提交_MySQL 事务提交过程
- 抓图软件_Faststone capture8.3
- 实验七:层叠样式表(二)
- PLSQL Developer 12 注册码
- java 汉字 数字_java数字转汉字工具类详解
- php 存储型跨站,php云人才系统存储型跨站两处
- python json数据的文件读写操作
- 多视角图像生成--Multi-View Image Generation from a Single-View