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;
}

github源代码

例子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; }

github源代码

例子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;
}

github源代码

运行方法:先运行接收端,再运行阻塞发送端。

从运行结果可以看出:阻塞的发送端,缓存区溢出后,write函数变成阻塞的了。

运行方法:先运行接收端,再运行非阻塞发送端。

从运行结果可以看出:非阻塞的发送端,缓存区溢出后,write函数是没有被调用的。

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信的更多相关文章

  1. c/c++ linux epoll系列3 利用epoll_wait设置timeout时间长度

    linux epoll系列3 利用epoll_wait设置timeout时间长度 epoll_wait函数的第四个参数可以设置,epoll_wait函数的等待时间(timeout时间长度). 例子1, ...

  2. c/c++ llinux epoll系列4 利用epoll_wait实现非阻塞的connect

    llinux epoll系列4 利用epoll_wait实现非阻塞的connect connect函数是阻塞的,而且不能设置connect函数的timeout时间,所以一旦阻塞太长时间,影响用户的体验 ...

  3. c/c++ llinux epoll系列5 解除epoll_wait状态

    linux epoll系列5 解除epoll_wait状态 有时候会有解除epoll_wait状态的需求. 实现方法: 1,给执行epoll_wait的程序发signal. 2,使用sockpair. ...

  4. c/c++ linux epoll系列1 创建epoll

    linux epoll系列1 创建epoll 据说select和poll的弱点是,随着连接(socket)的增加,性能会直线下降. epoll不会随着连接(socket)的增加,性能直线下降. 知识点 ...

  5. Linux NIO 系列(04-4) select、poll、epoll 对比

    目录 一.API 对比 1.1 select API 1.2 poll API 1.3 epoll API 二.总结 2.1 支持一个进程打开的 socket 描述符(FD)不受限制(仅受限于操作系统 ...

  6. 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_ ...

  7. Windows完成端口与Linux epoll技术简介

    收藏自:http://www.cnblogs.com/cr0-3/archive/2011/09/09/2172280.html WINDOWS完成端口编程1.基本概念2.WINDOWS完成端口的特点 ...

  8. epoll 系列函数简介、与select、poll 的区别

    一.epoll 系列函数简介 #include <sys/epoll.h> int epoll_create(int size); int epoll_create1(int flags) ...

  9. Java网络编程和NIO详解6:Linux epoll实现原理详解

    Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...

随机推荐

  1. Ubuntu12.04下安装NS3.25

    实验室项目的需求,要使用到NS3做仿真,使用实验室的电脑,Ubuntu12.04,版本比较低,建议大家使用16.04,这样安装依赖文件时不会出现版本过低的问题 (没管最后也安装成功了).下面就安装步骤 ...

  2. Python内置函数(61)——str

    英文文档: class str(object='') class str(object=b'', encoding='utf-8', errors='strict') Return a string ...

  3. 【Maven】---Linux搭建Nexus3.X私服

    Linux搭建Nexus3.X私服 备注:linux版本: ubuntu 同时已经部署好JDK8环境 一.linux安装nexus 1.创建文件夹并进入该目录 cd /usr/local && ...

  4. SpringCloud(6)---熔断降级理解、Hystrix实战

    SpringCloud(6)---熔断降级理解.Hystrix实战 一.概念 1.为什么需要熔断降级 (1)需求背景 它是系统负载过高,突发流量或者网络等各种异常情况介绍,常用的解决方案. 在一个分布 ...

  5. 从锅炉工到AI专家(6)

    欠拟合和过拟合 几乎所有的复杂方程都存在结果跟预期差异的情况,越复杂的方程,这种情况就越严重.这里面通常都是算法造成的,当然也存在数据集的个体差异问题. 所以"欠拟合"和" ...

  6. nginx部署~dotnetCore+mvc网站502

    这个不是nginx的问题,也不是dotnet core的问题,也不是mvc的问题,更不是防火墙的问题! 原因在于这个SeLinux 把它关了就可以了 setsebool -P httpd_can_ne ...

  7. Asp.Net SignalR 多平台的Client与Server

    多平台 SignalR在.Net的大环境下都可以做到即时通讯,也就是说都可以使用,客户端也不仅是js.下面就来一个控制台的Client 我们需要在nuget上下载包 Microsoft.AspNet. ...

  8. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->用户管理模块新增“重置用户密码”功能

    不管是什么系统登录用户都有忘记密码的时候,忘记密码就进入不了系统.系统应该可以提供重置用户密码的功能.在我们框架中重置用户密码功能一般用用户管理员来完成.当然如果做得复杂点还可以由用户自己来重置(如: ...

  9. Kubernetes 弹性伸缩全场景解析 (四)- 让核心组件充满弹性

    前言 在本系列的前三篇中,我们介绍了弹性伸缩的整体布局以及HPA的一些原理,HPA的部分还遗留了一些内容需要进行详细解析.在准备这部分内容的期间,会穿插几篇弹性伸缩组件的最佳实践.今天我们要讲解的是 ...

  10. webpack4.0各个击破(5)—— Module篇

    webpack4.0各个击破(5)-- Module篇 webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高.本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决 ...