非阻塞socket与epoll
fcntl函数调用设置非阻塞例子
int opts = fcntl(st, F_GETFL);
if (opts < )
{
printf("fcntl failed %s\n", strerror(errno));
}
opts = opts | O_NONBLOCK;
if (fcntl(st, F_SETFL, opts) < )
{
printf("fcntl failed %s\n", strerror(errno));
}
fcntl函数调用设置阻塞例子
if (fcntl(st, F_SETFL, ) < )
{
printf("fcntl failed %s\n", strerror(errno));
}
struct epoll_event结构如下:
typedef union epoll_data {
void *ptr;
int fd;
__uint32_t u32;
__uint64_t u64;
} epoll_data_t; struct epoll_event {
__uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h> ssize_t socket_recv(int st)
{
char buf[];
memset(buf, , sizeof(buf));
ssize_t rc = recv(st, buf, sizeof(buf), );
if (rc <= )
{
printf("recv failed %s\n", strerror(errno));
} else
{
printf("recv %s\n", buf);
send(st, buf, rc, );
}
return rc;
} int socket_accept(int listen_st)
{
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
memset(&client_addr, , sizeof(client_addr));
int client_st = accept(listen_st, (struct sockaddr *) &client_addr, &len);
if (client_st < )
printf("accept failed %s\n", strerror(errno));
else
printf("accept by %s\n", inet_ntoa(client_addr.sin_addr));
return client_st;
} void setnonblocking(int st) //将socket设置为非阻塞
{
int opts = fcntl(st, F_GETFL);
if (opts < )
{
printf("fcntl failed %s\n", strerror(errno));
}
opts = opts | O_NONBLOCK;
if (fcntl(st, F_SETFL, opts) < )
{
printf("fcntl failed %s\n", strerror(errno));
}
} int socket_create(int port)
{
int st = socket(AF_INET, SOCK_STREAM, );
int on = ;
if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -)
{
printf("setsockopt failed %s\n", strerror(errno));
return ;
}
struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(st, (struct sockaddr *) &addr, sizeof(addr)) == -)
{
printf("bind port %d failed %s\n", port, strerror(errno));
return ;
}
if (listen(st, ) == -)
{
printf("listen failed %s\n", strerror(errno));
return ;
}
return st;
} int main(int arg, char *args[])
{
if (arg < )
return -;
int iport = atoi(args[]);
int listen_st = socket_create(iport);
if (listen_st == )
return -; struct epoll_event ev, events[]; //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
int epfd = epoll_create(); //生成用于处理accept的epoll专用的文件描述符
setnonblocking(listen_st); //把socket设置为非阻塞方式
ev.data.fd = listen_st; //设置与要处理的事件相关的文件描述符
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP; //设置要处理的事件类型
epoll_ctl(epfd, EPOLL_CTL_ADD, listen_st, &ev); //注册epoll事件 int st = ;
while ()
{
int nfds = epoll_wait(epfd, events, , -); //等待epoll事件的发生
if (nfds == -)
{
printf("epoll_wait failed %s\n", strerror(errno));
break;
} int i;
for (i = ; i < nfds; i++)
{
if (events[i].data.fd < )
continue; if (events[i].data.fd == listen_st) //监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。
{
st = socket_accept(listen_st);
if (st >= )
{
setnonblocking(st);
ev.data.fd = st;
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP; //设置要处理的事件类型
epoll_ctl(epfd, EPOLL_CTL_ADD, st, &ev);
continue;
}
}
if (events[i].events & EPOLLIN) //socket收到数据
{
st = events[i].data.fd;
if (socket_recv(st) <= )
{
close(st);
events[i].data.fd = -;
}
}
if (events[i].events & EPOLLERR) //socket错误
{
close(st);
events[i].data.fd = -;
} if (events[i].events & EPOLLHUP) //socket错误
{
close(st);
events[i].data.fd = -;
}
}
}
close(epfd);
return ;
}
搜索
复制
非阻塞socket与epoll的更多相关文章
- Linux 网络编程七(非阻塞socket:epoll--select)
阻塞socket --阻塞调用是指调用结果返回之前,当前线程会被挂起.函数只有在得到结果之后才会返回. --对于文件操作 read,fread函数调用会将线程阻塞(平常使用read感觉不出来阻塞, 因 ...
- Linux - 非阻塞socket编程处理EAGAIN错误
在linux进行非阻塞的socket接收数据时经常出现Resource temporarily unavailable,errno代码为11(EAGAIN),这表明你在非阻塞模式下调用 ...
- JAVA基础知识之网络编程——-基于NIO的非阻塞Socket通信
阻塞IO与非阻塞IO 通常情况下的Socket都是阻塞式的, 程序的输入输出都会让当前线程进入阻塞状态, 因此服务器需要为每一个客户端都创建一个线程. 从JAVA1.4开始引入了NIO API, NI ...
- linux网络编程中阻塞和非阻塞socket的区别
读操作 对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返 回.当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数.当 ...
- 阻塞和非阻塞socket的区别
读操作 对于阻塞的socket,当socket的接收缓冲区中没有数据时,read调用会一直阻塞住,直到有数据到来才返回.当socket缓冲区中的数据量小于期望读取的数据量时,返回实际读取的字节数.当s ...
- 【2018.08.13 C与C++基础】网络通信:阻塞与非阻塞socket的基本概念及简单实现
一.前言 最近在做Matalb/Simulink与C/C++的混合编程,主要是完成TCP.UDP.SerialPort等常见通信方式的中间件设计,为Simulink模型提供数据采集及解析模块. 问题在 ...
- 斐讯面试记录—阻塞Socket和非阻塞Socket
文章出自:http://blog.csdn.net/VCSockets/ 1.TCP中的阻塞Socket和非阻塞Socket 阻塞与非阻塞是对一个文件描述符指定的文件或设备的两种工作方式. 阻塞的意思 ...
- 网络编程中阻塞和非阻塞socket的区别
阻塞socket和非阻塞socket 建立连接阻塞方式下,connect首先发送SYN请求道服务器,当客户端收到服务器返回的SYN的确认时,则connect返回.否则的话一直阻塞.非阻塞方式,conn ...
- 非阻塞socket调用connect, epoll和select检查连接情况示例
转自http://www.cnblogs.com/yuxingfirst/archive/2013/03/08/2950281.html 我们知道,linux下socket编程有常见的几个系统调用: ...
随机推荐
- session 丢失问题
1. 存到memcached中, 十分简单, 在使用session之前, 加入下面两行代码 int_set('session.save_handler', 'memcache'); int_set(' ...
- P1605 迷宫(洛谷)
题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫中移动有上下左右 ...
- 基于Python语言使用RabbitMQ消息队列(五)
Topics 在前面教程中我们改进了日志系统,相比较于使用fanout类型交易所只能傻瓜一样地广播,我们用direct获得了选择性接收日志的能力. 虽然使用direct类型交易所改进了我们的系统,但它 ...
- 洛谷【P1004】方格取数
浅谈\(DP\):https://www.cnblogs.com/AKMer/p/10437525.html 题目传送门:https://www.luogu.org/problemnew/show/P ...
- Azure VM复制
目前Azure上复制VM可以有多种方法: 1 创建User Image,可以快速复制多台VM,但目前托管磁盘只支持Generalized的模式,需要对User和配置进行重置. 2 从VHD或托管磁盘复 ...
- (转)NHibernate各种数据库配置写法
本文转载自:http://blog.csdn.net/hsg77/article/details/23463733 //NHibernate各种数据库连接参数文件配置方法说明 //配置文件Config ...
- AngularJS:参考手册
ylbtech-AngularJS:参考手册 1.返回顶部 1. AngularJS 参考手册 AngularJS 指令 本教程用到的 AngularJS 指令 : 指令 描述 ng-app 定义应用 ...
- Java开发Linux常用命令
linux下tomcat服务的相关命令 http://blog.csdn.net/zhangzhikaixinya/article/details/8224307 linux下实时查看tomcat运行 ...
- 新建 FrameMaker API 时引用目录的设置
如果将FDK安装目录下的Sample项目拷贝到其它目录编译,往往会报错 c1083 找不到fapi.h等头文件,或者Link时报错找不到.lib文件. 1.可通过菜单-项目-xxx属性-配置属性-c/ ...
- Eloquent ORM模型中添加自定义值
我们都知道通过Laravel中数据库查询出来的模型对象都是基于数据库字段,今天给大家展示一个 Laravel Eloquent ORM 模型特性-附加值不存在于数据表中. 举个简单的栗子,一篇文章(p ...