socket阻塞和非阻塞
来源:互联网 发布:最全家庭网络投资理财 编辑:程序博客网 时间:2024/05/16 07:18
Linux的网络编程有很多种写法,最简单的是阻塞式(Blocking)的网络程序,其次有非阻塞(Non-Blocking),多路复用(Multiplexing),异步(Asynchronous)模型等。
阻塞模型:
阻塞模型是最为简单的一种网络编程模型。顾名思义,该模型中,socket都工作在阻塞模式下,在调用相应的网络函数时,如accept, recv, send时,这些函数都会阻塞线程,直到socket可读或者可写,或者出错时,线程才会继续执行。
在阻塞模式下,我们一般用多线程来对每一个socket进行处理,一个线程服务一次链接,这种模型在一些web服务器中较为常见,如apache,tomcat等
扩展pthread_create函数:
int pthread_create(pthread_t *thread,pthread_attr_t *attr,(void *(*start_routine)(void *),void *arg));
其中第二个参数设置线程属性(线程栈大小,线程优先级等)
第三个参数为线程函数的起始地址
第四个参数为传递给线程函数的参数
会阻塞的socket的API:
accept,connect,recv(recvfrom),send(sendto),closesocket,select(poll/epoll)
非阻塞模型:
非阻塞模型,顾名思义,socket工作在非阻塞模式中,这时对该socket调用相应的函数时,并不会阻塞线程运行,即便没有数据准备好,这些函数也会立即返回,线程将继续执行。那我们将需要在后面的代码中,对返回的结果进行判断,以区分刚才的调用是否有数据可以处理。
非阻塞模型的优点在于,可以在一个线程中处理多个socket事件,而不会阻塞线程,减少多线程切换带来的开销。相应的,也增加了处理的复杂度。
设置为非阻塞
int flags = fcntl(fd,F_GETFL,0);
fcntl(fd,F_SETFL,flags | O_NONBLOCK);
设置为阻塞
int flags = fcntl(fd,F_GETFL,0);
fcntl(fd,F_SETFL,flags &~ O_NONBLOCK);
非阻塞socket代码逻辑(recv):
while(1){ char buff[1024] = {0}; int num = recv(fd,buff,sizeof(buff),0); if(num > 0) { //recv成功 接收到数据 } else if(num < 0) { if((errno == EAGAIN || errno == EWOULDBLOCK)) { //非阻塞 连接正常 EAGAIN EWOULDBLOCK 表示在没有数据到来时的返回 //可以处理一些事件 continue; } else { //error break; } }}
阻塞和非阻塞函数行为差异:
- accept在阻塞模式下,没有新连接时,线程会进入睡眠状态;非阻塞模式下没有新连接立即返回并设置errno为WOULDBLOCK
- connect在阻塞模式下,仅TCP连接建立成功或出错时才返回;非阻塞模式下,该函数会立即返回INPROCESS错误(需用select检测该连接是否建立成功)
- recv/recvfrom/send/sendto很好理解,因为这两类函数读写socket文件描述符的接收/发送缓冲区
- closesocket也不是真正意义上的阻塞,它其实是指是否等待关闭,它受套接字选项SO_LINGER和SO_DONTLINGER的影响。若SO_DONTLINGER或SO_LINGER的间隔=0时,closesocket就是非等待关闭的,但是当SO_LINGER的间隔>0时,closesoket就是等待关闭的,直到剩余数据都发送完毕或直到超时才退出。(但是这个地方只有对于阻塞的套接口才有用,如果是非阻塞的套接口,它会立即返回并且指示错误WOULDBLOCK)
- socket 阻塞和非阻塞
- socket阻塞和非阻塞
- 阻塞socket和非阻塞socket
- 转阻塞socket和非阻塞socket
- 阻塞socket和非阻塞socket(二)
- 阻塞Socket和非阻塞Socket
- 阻塞非阻塞socket
- socket阻塞,非阻塞
- socket阻塞和非阻塞的区别
- socket阻塞和非阻塞的区别
- socket阻塞和非阻塞的区别
- socket阻塞和非阻塞的区别
- socket阻塞和非阻塞的区别
- socket 同步、异步、阻塞和非阻塞
- window socket 阻塞和非阻塞通信
- socket阻塞和非阻塞的区别
- socket阻塞 和 非阻塞设置
- Socket 阻塞模式和非阻塞模式
- spring+mybatis做单元测试报错IllegalStateException
- keras中文文档笔记7——序贯模型
- keras中文文档笔记8——函数式模型
- 深入Java虚拟机之类加载
- js 实现PHP中的in_array()
- socket阻塞和非阻塞
- 机器学习基石系列一
- MySQL的Date数据0000-00-00报错
- Hello, world
- 真Unity3d_我的AR初体验
- Pillow库的使用+图片转字符串
- SpringMVC和mybatis整合时遇见的错误
- tensorflow 卷积神经网络 LeNet-5模型 MNIST手写体数字识别
- MongoDB 中文显示乱码的 真正原因和解决方案,真的是cmd问题吗?