c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信
linux epoll系列2 利用epoll_wait查看是否可以送信
write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变成了阻塞了,这个进程或者线程就堵住了,不能被响应了。
epoll_wait函数可以判断出,缓存区是否可写,可写后再调用write函数,这样就避免了write函数被阻塞。
例子1,是接收端。
例子2, 是会发生阻塞的发送端。
例子3,利用了epoll_wait,所以是不会发生阻塞的。
例子1,接收端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
int main(){
int sock0;
sockaddr_in addr;
sockaddr_in client;
socklen_t len;
int sock;
int n;
char buf[65536];
int i;
sock0 = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.s_addr = INADDR_ANY;
bind(sock0, (sockaddr*)&addr, sizeof(addr));
listen(sock0, 5);
len = sizeof(client);
sock = accept(sock0, (sockaddr*)&client, &len);
printf("after accept\n");
for(i = 0; i < 10; ++i){
sleep(2);
n = read(sock, buf, sizeof(buf));
printf("recv data size:[%d] bytes\n", n);
}
printf("close socket and finish\n");
close(sock);
return 0;
}
例子2, 是会发生阻塞的发送端。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
int main(){
sockaddr_in server;
int sock;
char buf[65536];
int n;
sock = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr);
n = connect(sock, (sockaddr*)&server, sizeof(server));
if(n != 0){
perror("connect");
return 1;
}
int cnt = 0;
while(1){
++cnt;
printf("[%d]write %ld bytes\n", cnt, sizeof(buf));
n = write(sock, buf, sizeof(buf));
if(n <= 0){
printf("write error:%d\n", n);
break;
}
}
close(sock);
return 0;
}
例子3,利用了epoll_wait,所以是不会发生阻塞的。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#define EVENTS 12
int main(){
sockaddr_in server;
epoll_event ev, ev_ret[EVENTS];
int sock, epfd;
char buf[65536];
int nfds;
int n;
sock = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_port = htons(12345);
inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr);
n = connect(sock, (sockaddr*)&server, sizeof(server));
if(n != 0){
perror("connect");
return 1;
}
epfd = epoll_create(2);
if(epfd < 0){
perror("epfd");
return 1;
}
memset(&ev, 0, sizeof(ev));
ev.events = EPOLLOUT;//可写
ev.data.fd = sock;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, sock, &ev) != 0){
perror("epoll_clt");
return 1;
}
int cnt = 0;
while(1){
cnt++;
printf("before epoll wait\n");
nfds = epoll_wait(epfd, ev_ret, EVENTS, -1);
if(nfds < 0){
perror("epoll_wait");
return 1;
}
printf("after epoll_wait\n");
if(ev_ret[0].data.fd == sock){
printf("[%d]write %ld types\n", cnt, sizeof(buf));
n = write(sock, buf, sizeof(buf));
if(n <= 0){
printf("write error:%d\n", n);
break;
}
}
}
close(sock);
return 0;
}
运行方法:先运行接收端,再运行阻塞发送端。
从运行结果可以看出:阻塞的发送端,缓存区溢出后,write函数变成阻塞的了。
运行方法:先运行接收端,再运行非阻塞发送端。
从运行结果可以看出:非阻塞的发送端,缓存区溢出后,write函数是没有被调用的。
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信的更多相关文章
- c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度
linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...
- c/c++ llinux epoll系列4 利用epoll_wait实现非阻塞的connect
llinux epoll系列4 利用epoll_wait实现非阻塞的connect connect函数是阻塞的,而且不能设置connect函数的timeout时间,所以一旦阻塞太长时间,影响用户的体验 ...
- c/c++ llinux epoll系列5 解除epoll_wait状态
linux epoll系列5 解除epoll_wait状态 有时候会有解除epoll_wait状态的需求. 实现方法: 1,给执行epoll_wait的程序发signal. 2,使用sockpair. ...
- c/c++ linux epoll系列1 创建epoll
linux epoll系列1 创建epoll 据说select和poll的弱点是,随着连接(socket)的增加,性能会直线下降. epoll不会随着连接(socket)的增加,性能直线下降. 知识点 ...
- Linux NIO 系列(04-4) select、poll、epoll 对比
目录 一.API 对比 1.1 select API 1.2 poll API 1.3 epoll API 二.总结 2.1 支持一个进程打开的 socket 描述符(FD)不受限制(仅受限于操作系统 ...
- Linux NIO 系列(04-3) epoll
目录 一.why epoll 1.1 select 模型的缺点 1.2 epoll 模型优点 二.epoll API 2.1 epoll_create 2.2 epoll_ctl 2.3 epoll_ ...
- Windows完成端口与Linux epoll技术简介
收藏自:http://www.cnblogs.com/cr0-3/archive/2011/09/09/2172280.html WINDOWS完成端口编程1.基本概念2.WINDOWS完成端口的特点 ...
- epoll 系列函数简介、与select、poll 的区别
一.epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
随机推荐
- 老司机教你用原生JDK 撸一个 MVC 框架!!!
其实 Spring MVC 是一个基于请求驱动的 Web 框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器进行处理,具体工作原理见下图. 在这里,就不详细谈相关的原 ...
- 11.Git分支-远程跟踪分支的概念、多个远程仓库的使用
1.远程跟踪分支的概念 远程引用是对远程仓库的引用,包括分支.标签等等. 1.可以通过 git ls-remote <remote> 来获得远程引用的完整列表 2.git remote ...
- java线程阻塞唤醒的四种方式
java在多线程情况下,经常会使用到线程的阻塞与唤醒,这里就为大家简单介绍一下以下几种阻塞/唤醒方式与区别,不做详细的介绍与代码分析 suspend与resume Java废弃 suspend() 去 ...
- asp.net core 系列 17 通用主机 IHostBuilder
一.概述 ASP.NET Core 通用主机 (HostBuilder),该主机对于托管不处理 HTTP 请求的应用非常有用.通用主机的目标是将 HTTP 管道从 Web 主机 API 中分离出来,从 ...
- sql server 性能调优之 SQL语句阻塞查询
在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,确定web服务器无故障后.就需要检查数据库是否有出现阻塞 当时数据库的生产环境中主表数据量超过2000w, ...
- leetcode — path-sum-ii
import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Source : https://o ...
- Flask入门之完整项目搭建
一.创建虚拟环境 1,新建虚拟环境 cmd中输入:mkvirtualenv 环境名 2,在虚拟环境安装项目运行所需要的基本模块 pip install flask==0.12.4 pip instal ...
- javascript sort 函数用法
sort 函数 博客地址:https://ainyi.com/41 简单的说,sort() 在没有参数时,返回的结果是按升序来排列的.即字符串的Unicode码位点(code point)排序 [5, ...
- JavaScript小实例:拖拽应用(二)
经常在网站别人的网站的注册页中看到一个拖拽验证的效果,就是它的验证码刚开始不出来,而是有一个拖拽的条,你必须将这个拖拽条拖到底,验证码才出来,说了感觉跟没说一样,你还是不理解,好吧,我给个图你看看: ...
- 第30章 部署 - Identity Server 4 中文文档(v1.0.0)
您的身份服务器只是一个标准的ASP.NET Core应用程序,包括IdentityServer中间件.首先阅读有关发布和部署的官方Microsoft 文档(尤其是有关负载平衡器和代理的部分). 30. ...