高级Socket编程——阻塞与非阻塞模式Socket编程
来源:互联网 发布:为什么不能下载java 编辑:程序博客网 时间:2024/05/22 17:02
http://www.tanhp.com/index.php/archives/219/
默认情况下,新建的Socket是阻塞模式的。可以调用 ioctlsocket()
函数将Socket设置为非阻塞模式,函数原型如下:
int ioctlsocket(SOCKET s,long cmd,u_long* argp)
参数说明:
s
:Socket句柄;
cmd
:在 s
上执行的命令;
argp
:指针变量,指定 cmd
命令的参数,当 cmd
设为 FIONBIO
时, argp
非0,表示启用非阻塞模式。
1、非阻塞模式服务器
(1)接收来自客户端请求
由于启用非阻塞模式, accept
函数调用后会立即返回,无论是否有客户连接,所以需要每隔一段时间调用探测。
client=accept(server,(sockaddr*)&cAddr,&len);if(client==INVALID_SOCKET){ int err=WSAGetLastError(); // 当前socket被表示为非阻塞,没有连接 if(err==WSAEWOULDBLOCK) { Sleep(100); continue; } else { cout<<"accept error"<<endl; closesocket(server); WSACleanup(); return -1; }}
(2)接收数据 同样的,接收数据、发送数据也要循环探测,知道成功为止
while(true){ // 接收数据[循环测试] ZeroMemory(buf,BUF_SIZE); retVal=recv(client,buf,BUF_SIZE,0); if(retVal==SOCKET_ERROR) { int err=WSAGetLastError(); if(err==WSAEWOULDBLOCK) { Sleep(100); continue; } else if(err==WSAETIMEDOUT||err==WSAENETDOWN) { closesocket(server); closesocket(client); WSACleanup(); return -1; } }cout<<"Recv data:"<<buf<<endl;
(3)发送数据
while(true){ retVal=send(client,buf,sizeof(buf),0); if(retVal==SOCKET_ERROR) { int err=WSAGetLastError(); if(err==WSAEWOULDBLOCK) { Sleep(100); continue; } else { closesocket(server); closesocket(client); WSACleanup(); return -1; } } break; }}
2、非阻塞模式客户端
同非阻塞服务器
3、非阻塞模式多线程服务器
上面介绍的服务器应用程序是单线程的,也就是说服务器在同一时刻只能与一个客户进行通信,这显然无法满足实际应用需求。
我们设计这样一个多线程服务器,主线程(即 main()
函数)负责介绍来自客户的连接请求,然后创建专门与客户端进行通信的子线程。
while(true){ client=accept(server,(sockaddr*)&caddr,&len); if(client==INVALID_SOCKET) { int err=WSAGetLastError(); if(err==WSAEWOULDBLOCK) { Sleep(100); continue; } else { return -1; } } else { // 创建新线程 tmpSocket[i]=client; _beginthreadex(NULL,0,AnswerThread,&tmpSocket[i],0,NULL); }}
特别需要注意的是,每次创建线程时传入的 SOCKET
指针不要使用全局的 client
,需要另外创建 tmpSocket
数组保存每次连接,这样避免了多个客户端连接多同一个 client
进行修改。
或者将 SOCKET
强制转换为 void *
,这样可以直接将 client
作为实参调用。
_beginthreadex(NULL,0,AnswerThread,(void*)client,0,NULL); // 调用SOCKET client=(SOCKET)lp; // 线程函数
0 0
- 高级Socket编程——阻塞与非阻塞模式Socket编程
- socket编程 —— 非阻塞socket
- socket编程 —— 非阻塞socket
- socket编程 —— 非阻塞socket
- socket编程中的阻塞与非阻塞
- 非阻塞socket编程
- 非阻塞socket编程
- 非阻塞socket编程
- 非阻塞Socket编程
- 非阻塞socket编程
- C++非阻塞模式Socket编程
- 阻塞非阻塞SOCKET-同异步编程
- linux C socket编程 — 阻塞式与非阻塞式
- Socket编程中,阻塞与非阻塞的区别
- iphone开发-socket 编程,阻塞与非阻塞
- Socket编程中,阻塞与非阻塞的区别
- Socket编程中,阻塞与非阻塞的区别
- socket编程的同步、异步与阻塞、非阻塞示例
- Git的使用十三(分支管理策略)仅限Mac亲测
- OC之set方法内存管理
- poj 1459 Power Network
- osgi8——camel activitimq
- 使用Python的requests库作接口测试——对HPPT动词的支持
- 高级Socket编程——阻塞与非阻塞模式Socket编程
- 图片缓存库Picasso和ImageLoader的使用
- 使用axis2配置webservice服务
- OC之@class
- hadoop2.x编译(三)
- 利用Amazon Mobile Analytics与R深入探究移动应用的使用模式
- 音频编码
- 正则表达式校验及实例
- Activity生命周期的简单了解