非阻塞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编程有常见的几个系统调用: ...
随机推荐
- 242. Valid Anagram Add to List
Given two strings s and t, write a function to determine if t is an anagram of s. For example,s = &q ...
- LeetCode Number of Longest Increasing Subsequence
原题链接在这里:https://leetcode.com/problems/number-of-longest-increasing-subsequence/description/ 题目: Give ...
- mysql之 xtrabackup原理、备份日志分析、备份信息获取
一. xtrabackup备份恢复工作原理: extrabackup备份简要步骤 InnoDB引擎很大程度上与Oracle类似,使用redo,undo机制,XtraBackup在备份的时候,以read ...
- python面向对象-我的理解
参考:博客 Vamei .廖雪峰 面向对象概念 面向对象完全可以按照自然界生物分类法来理解. 当然,它不会有自然界那么复杂. 因为我专业的关系,因此个人觉得微生物来举例很容易理解. 所有的微生物都具有 ...
- boost_1.61.0编译安装
1.下载源码boost_1_61_0.zip 2.进入目录 C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shor ...
- Gradle 配置
下载Gradle https://gradle.org/releases/ https://services.gradle.org/distributions/gradle-4.4.1-bin.zip ...
- 【转】Inter-eNB S1 切换
本博客介绍Inter-eNB的S1切换的流程 当eNB收到测量报告,或是因为内部负荷分担等原因,触发了切换判决,进行eNB间小区间通过S1口的切换. 源eNB通过S1接口的 HANDOVER REQU ...
- java继承初级
总结:重写方法,方法体内容不同. 还有子类都不能加public.它表示公共,一个程序只能有一个公共类 package com.sa; public class Ac { public void rea ...
- AngularJS:依赖注入
ylbtech-AngularJS:依赖注入 1.返回顶部 1. AngularJS 依赖注入 什么是依赖注入 wiki 上的解释是:依赖注入(Dependency Injection,简称DI)是一 ...
- Rails、Nginx、Passenger、bundle之间的协作关系
引自:http://www.zhihu.com/question/20062163 Bundle是Gem包的依赖管理工具,RubyGem本身有依赖管理为何还要Bundle呢?有时候两个gem虽然都依赖 ...