c/c++语言开发共享c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信

linux epoll系列2 利用epoll_wait查看是否可以送信 write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变成了阻塞了,这个进程或者线程就堵住了,不能被响应了。 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 acceptn");    for(i = 0; i < 10; ++i){     sleep(2);     n = read(sock, buf, sizeof(buf));     printf("recv data size:[%d] bytesn", n);   }    printf("close socket and finishn");    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 bytesn", cnt, sizeof(buf));     n = write(sock, buf, sizeof(buf));     if(n <= 0){       printf("write error:%dn", 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 waitn");      nfds = epoll_wait(epfd, ev_ret, events, -1);     if(nfds < 0){       perror("epoll_wait");       return 1;     }      printf("after epoll_waitn");      if(ev_ret[0].data.fd == sock){       printf("[%d]write %ld typesn", cnt, sizeof(buf));        n = write(sock, buf, sizeof(buf));       if(n <= 0){     printf("write error:%dn", n);     break;       }     }   }    close(sock);   return 0; }

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

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

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

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

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

c/c++ linux epoll系列2 利用epoll_wait查看是否可以送信

本人微信:xiaoshitou5854

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/606799.html

(0)
上一篇 2021年5月14日
下一篇 2021年5月14日

精彩推荐