非阻塞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编程有常见的几个系统调用: ...
随机推荐
- lower_bound()函数与quicksort()函数的简单掌握
lower_bound 这个序列中可能会有很多重复的元素,也可能所有的元素都相同,为了充分考虑这种边界条件,STL中的lower_bound算法总体上是才用了二分查找的方法,但是由于是查找序列中的第一 ...
- LeetCode Shopping Offers
原题链接在这里:https://leetcode.com/problems/shopping-offers/description/ 题目: In LeetCode Store, there are ...
- Qt中如何用QImage::Format_Indexed8表示灰度图
QImage *qi = new QImage(data_ptr, width, height, QImage::Format_Indexed8); QVector<QRgb> grayT ...
- 引用 WCF 服务后,没有生成任何 .datasource?
如题WCF服务生成成功,在添加服务引用的时候也不报错,但是添加完成之后不能正常调用服务借口. 在重新引用服务的时候,或者是是更新引用服务的时候,点“高级”按钮,在服务引用设置对话框中,将“重新使用引用 ...
- Java类与继承
Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相 ...
- Oracle 文件
参数文件 跟踪文件 告警文件 数据文件 临时文件 控制文件 重做日志文件 密码文件 闪回日志 dum文件 数据泵文件 1参数文件 Parameter file:告诉oracle实例在那里可以找到控制文 ...
- Rails的静态资源管理(四)—— 生产环境的 Asset Pipeline
官方文档:http://guides.ruby-china.org/asset_pipeline.html http://guides.rubyonrails.org/asset_pipeline.h ...
- phonegap制作windows phone包
下载SDK win7及以下版本下载SDK http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=27570 WIN8下载SDK ht ...
- mysql 回顾小练习
Student(id,sname,age,sex) 学生表 Course(id,cname,t_id) 课程表 SC(s_id,c_id,score) 成绩表 Teacher(id,Tname) 教师 ...
- 在Google Colab中导入一个本地模块或.py文件
模块与单个.py文件的区别,模块中含有__init__.py文件,其中函数调用使用的是相对路径,如果使用导入.py文件的方法在Google Colab中导入模块 会报错:Attempted relat ...