/*
*
*EPOLL ET 触发必须使用非阻塞,LT触发可以阻塞/非阻塞。
*read 函数 非阻塞读需 忙轮寻 soket关闭返回0,循环读完数据
*如果已经读完再读read返回 -1,errno=11(EAGIAN)则退出轮循
*
**/ #include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/select.h>
#include<sys/time.h>
#include<pthread.h>
#include<memory.h>
#include<errno.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<signal.h>
#include<semaphore.h>
#include<malloc.h>
#include<fcntl.h>
#include<sys/epoll.h> typedef unsigned int uint32; pthread_mutex_t lock;
uint32 qcount=; typedef struct{
int flag;
sem_t sem;
}MYLOCK; struct sockaddr_in server;
MYLOCK mlock;
int g_epfd=-; void printerror()
{
printf("%d:%s\n",errno,strerror(errno));
exit(-);
} void* th_hand(void* p){
sem_wait(&mlock.sem);
while(!mlock.flag){
sem_post(&mlock.sem);
sleep();
sem_wait(&mlock.sem);
}
sem_post(&mlock.sem);
struct epoll_event events[];
struct epoll_event event;
while(){
memset(&event,,sizeof(struct epoll_event));
memset(events,,sizeof(struct epoll_event)*);
int s = epoll_wait(g_epfd,events,,);
if(s==-){
printerror();
}else if(s==){
continue;
}else if(s>){
for(int i=;i<s;i++){
int fd=events[i].data.fd;
char buff[];
while(){
int rd=-;
memset(buff,,sizeof(buff));
rd=read(fd,buff,sizeof(buff)-);
if(rd==){
struct sockaddr_in client;
memset(&client,,sizeof(client));
int len=sizeof(client);
getpeername(fd,(struct sockaddr*)&client,&len);
printf("client %s is closed fd is %d , bye!\n",inet_ntoa(client.sin_addr),fd);
close(fd);
event.data.fd=fd; sem_post(&mlock.sem);
epoll_ctl(g_epfd,EPOLL_CTL_DEL,fd,&event);
sem_wait(&mlock.sem);
break;
}else if(rd>){
int wr=write(STDOUT_FILENO,buff,rd);
}else if(rd==-){
if(errno==EAGAIN)
break;
printerror();
}
}
}
}
}
}
int initSocket(int port){
memset(&server,,sizeof(server));
server.sin_family=AF_INET;
server.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY==0
server.sin_port=htons(port);
int sockfd=socket(AF_INET,SOCK_STREAM,);
if(sockfd==-){
printerror();
}
int res=bind(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr));
if(res==-){
printerror();
}
if(-==listen(sockfd,)){
printerror();
} g_epfd=epoll_create();
if(g_epfd==-){
printerror();
} sem_wait(&mlock.sem);
mlock.flag=;
sem_post(&mlock.sem); printf("main before accept\n");
while(){
int fd;
if((fd=accept(sockfd,NULL,NULL))==-){
printerror();
}
printf("fd %d is connect\n",fd);
struct epoll_event event;
// event.events=EPOLLIN;
event.events=EPOLLIN|EPOLLET;
event.data.fd=fd; fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,)|O_NONBLOCK); sem_wait(&mlock.sem);
if(-==(epoll_ctl(g_epfd,EPOLL_CTL_ADD,fd,&event))){
printerror();
}
qcount++;
sem_post(&mlock.sem);
}
} void sig_hand(int signo){
if(signo==SIGINT){
printf("have %d client\n",qcount);
exit();
}
} pthread_t pid; int main(int argc,char** argv){
if(argc<){
puts("please input port\n");
exit(-);
}
int port=atoi(argv[]);
signal(SIGINT,sig_hand);
memset(&mlock,,sizeof(mlock));
sem_init(&mlock.sem,,);
mlock.flag=;
pthread_create(&pid,NULL,th_hand,(void*));
pthread_detach(pid);
initSocket(port); }

linux epoll ET边沿触发的更多相关文章

  1. Server Develop (六) Linux epoll总结

    Linux  epoll epoll是Kernel 2.6后新加入的事件机制,在高并发条件下,远优于select.epoll最大的好处在于它不会随着监听fd数目的增长而降低效率.因为在内核中的sele ...

  2. Linux epoll总结

    Linux epoll总结 Linux  epoll epoll是Kernel 2.6后新加入的事件机制,在高并发条件下,远优于select.epoll最大的好处在于它不会随着监听fd数目的增长而降低 ...

  3. 如何在Python中使用Linux epoll

    如何在Python中使用Linux epoll 内容 介绍 阻塞套接字编程示例 异步套接字和Linux epoll的好处 epoll的异步套接字编程示例 性能考量 源代码 介绍 从2.6版开始,Pyt ...

  4. Linux Epoll介绍和程序实例

    Linux Epoll介绍和程序实例 1. Epoll是何方神圣? Epoll但是当前在Linux下开发大规模并发网络程序的热门人选,Epoll 在Linux2.6内核中正式引入,和select类似, ...

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

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

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

    linux epoll系列2 利用epoll_wait查看是否可以送信 write函数本来是非阻塞函数,但是当缓存区被写满后,再往缓存区里写的时候,就必须等待缓存区再次变成可写,所以这是write就变 ...

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

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

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

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

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

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

随机推荐

  1. Vulkan SDK 之 Device

     Enumerate Physical Devices Vulkan instance创建完成之后,vulkan loader是知道你有几个物理设备(显卡),但是程序不知道,需要通过 相关接口获取设备 ...

  2. Flink集群模式部署及案例执行

    一.软件要求 Flink在所有类UNIX的环境[例如linux,mac os x和cygwin]上运行,并期望集群由一个 主节点和一个或多个工作节点组成.在开始设置系统之前,确保在每个节点上都安装了一 ...

  3. JDBC批处理方法

    每次新建Connection的时候相当于建了一座桥,每次一辆车(PreparedStatement)运送货物(ResultSet)成本太高! 每次都建立网络连接的时间远远大于本地的时间,为了处理大量的 ...

  4. swift中利用系统线程实现异步加载数据同步更新UI

    swift中的使用案例样式 // Mark: -数据源更新 typealias AddDataBlock = () ->Void var updataBlock:AddDataBlock? fu ...

  5. torch.Tensor文档学习笔记

    A torch.Tensor is a multi-dimensional matrix containing elements of a single data type. 张量(torch.Ten ...

  6. Java 语言特性【一】——JUC(Java 并发工具包)

    引言 JUC即java.util.concurrent,是java提供的用于多线程处理的工具类库.重点关注 ConcurrentXXX.AtomicXXX.Executor.Caller&&a ...

  7. java 继承条件下的构造方法调用

    运行 TestInherits.java示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个构造函数,注意这句调用代码是否是第 ...

  8. 经典线段树 UVALive 3938/UVA 1400

    题意:就是相当于动规里面的求最大连续子串,不同的是,这里需要读入一个区间x,y,输出的区间 a,b 且x<=a<=b<=y,使得a b的连续子串最长,而且询问次数达到了10的五次方. ...

  9. 【MySQL 组复制】1.组复制技术简介

    组复制有两种模式 单主模式(single-primary/single-master)下自动选举出一个主节点,从而只允许在同一时刻只有该主节点可以更新数据. 对于MySQL的高级使用人员,可以通过复制 ...

  10. Jetson TX2入门学习之Ubuntu默认密码

    在使用TX2开发板时进行软件更新时需要身份验证,TX2默认有两个登录身份,一个是ubuntu 一个是nvidia 登录其中的哪一个都可以更新   两个身份的密码和登录名是一样的用户:ubuntu 密码 ...