epoll+socket实现 socket并发 linux服务器
/* 实现功能:通过epoll, 处理多个socket
* 监听一个端口,监听到有链接时,添加到epoll_event
* xs
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <poll.h>
#include <sys/epoll.h>
#include <sys/time.h>
#include <netinet/in.h>
#define MYPORT 12345
//最多处理的connect
#define MAX_EVENTS 500
//当前的连接数
int currentClient = 0;
//数据接受 buf
#define REVLEN 10
char recvBuf[REVLEN];
//epoll描述符
int epollfd;
//事件数组
struct epoll_event eventList[MAX_EVENTS];
void AcceptConn(int srvfd);
void RecvData(int fd);
int main()
{
int i, ret, sinSize;
int recvLen = 0;
fd_set readfds, writefds;
int sockListen, sockSvr, sockMax;
int timeout;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
//socket
if((sockListen=socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket error\n");
return -1;
}
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(MYPORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//bind
if(bind(sockListen, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0)
{
printf("bind error\n");
return -1;
}
//listen
if(listen(sockListen, 5) < 0)
{
printf("listen error\n");
return -1;
}
// epoll 初始化
epollfd = epoll_create(MAX_EVENTS);
struct epoll_event event;
event.events = EPOLLIN|EPOLLET;
event.data.fd = sockListen;
//add Event
if(epoll_ctl(epollfd, EPOLL_CTL_ADD, sockListen, &event) < 0)
{
printf("epoll add fail : fd = %d\n", sockListen);
return -1;
}
//epoll
while(1)
{
timeout=3000;
//epoll_wait
int ret = epoll_wait(epollfd, eventList, MAX_EVENTS, timeout);
if(ret < 0)
{
printf("epoll error\n");
break;
}
else if(ret == 0)
{
printf("timeout ...\n");
continue;
}
//直接获取了事件数量,给出了活动的流,这里是和poll区别的关键
int i = 0;
for(i=0; i<ret; i++)
{
//错误退出
if ((eventList[i].events & EPOLLERR) ||
(eventList[i].events & EPOLLHUP) ||
!(eventList[i].events & EPOLLIN))
{
printf ( "epoll error\n");
close (eventList[i].data.fd);
return -1;
}
if (eventList[i].data.fd == sockListen)
{
AcceptConn(sockListen);
}else{
RecvData(eventList[i].data.fd);
}
}
}
close(epollfd);
close(sockListen);
return 0;
}
/**************************************************
函数名:AcceptConn
功能:接受客户端的链接
参数:srvfd:监听SOCKET
***************************************************/
void AcceptConn(int srvfd)
{
struct sockaddr_in sin;
socklen_t len = sizeof(struct sockaddr_in);
bzero(&sin, len);
int confd = accept(srvfd, (struct sockaddr*)&sin, &len);
if (confd < 0)
{
printf("bad accept\n");
return;
}else
{
printf("Accept Connection: %d", confd);
}
//将新建立的连接添加到EPOLL的监听中
struct epoll_event event;
event.data.fd = confd;
event.events = EPOLLIN|EPOLLET;
epoll_ctl(epollfd, EPOLL_CTL_ADD, confd, &event);
}
//读取数据
void RecvData(int fd)
{
int ret;
int recvLen = 0;
memset(recvBuf, 0, REVLEN);
printf("RecvData function\n");
if(recvLen != REVLEN)
{
while(1)
{
//recv数据
ret = recv(fd, (char *)recvBuf+recvLen, REVLEN-recvLen, 0);
if(ret == 0)
{
recvLen = 0;
break;
}
else if(ret < 0)
{
recvLen = 0;
break;
}
//数据接受正常
recvLen = recvLen+ret;
if(recvLen<REVLEN)
{
continue;
}
else
{
//数据接受完毕
printf("buf = %s\n", recvBuf);
recvLen = 0;
break;
}
}
}
printf("data is %s", recvBuf);
}
epoll+socket实现 socket并发 linux服务器的更多相关文章
- linux服务器最大连接数
1 受内存限制 每个tcp连接是一个打开的socket文件,因此linux服务器的最大连接数受linux操作系统单个进程同时打开的最大文件数的限制. 这个限制本质上是对单个进程内存的限制. 查看进程最 ...
- Linux网络服务器epoll模型的socket通讯的实现(一)
准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...
- 网络编程socket 结合IO多路复用select; epool机制分别实现单线程并发TCP服务器
select版-TCP服务器 1. select 原理 在多路复用的模型中,比较常用的有select模型和epoll模型.这两个都是系统接口,由操作系统提供.当然,Python的select模块进行了 ...
- 一小时学会用Python Socket 开发可并发的FTP服务器!!
socket是什么 什么是socket所谓socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求 ...
- socket编程之并发回射服务器
使用到的函数: // 子进程返回0,父进程返回子进程ID,出错返回-1 pid_t fork(void); pid_t wait(int *wstatus); // 最常用的option是WNOHAN ...
- Linux Xshell连接Linux服务器时报错Socket error Event: 32 Error: 10053
问题描述 在用Xshell连接Linux服务器时,出现错误提示"Socket error Event: 32 Error: 10053. Connection closing...Socke ...
- socket编程之并发回射服务器3
在socket编程之并发回射服务器一文中,服务器采用多进程的方式实现并发,本文采用多线程的方式实现并发. 多线程相关API: // Compile and link with -pthread int ...
- socket编程之并发回射服务器2
承接上文:socket编程之并发回射服务器 为了让服务器进程的终止一经发生,客户端就能检测到,客户端需要能够同时处理两个描述符:套接字和用户输入. 可以使用select达到这一目的: void str ...
- Linux服务器高并发实践经历
作为一个师父离职早的野生程序员,业务方面还可以达到忽悠别人的水平,但上升到性能层面那就是硬伤. 真实天上掉馅饼,公司分配了一个测试性能的任务,真是感觉我的天空星星都亮了. 高并发主要限制因素:CPU. ...
随机推荐
- 如何在hadoop上做等频离散化
抛砖引玉,先根据特征值group by,统计每个特征值出现次数,然后reduce到一个文件,根据一个文件来统计吧,毕竟,你知道多个桶,那么每个桶多少个样本就是确定了,数数,数到一个桶样本的时候停止,就 ...
- django模型系统(二)
django模型系统(二) 常用查询 每一个django模型类,都有一个默认的管理器,objects QuerySet表示数据库中对象的列表.他可以有0到国歌过滤器.过滤器通过给定参数,缩小查询范围( ...
- linux命令三剑客之一sed
a(a\或者a\\):在当前行后面加入一行文本sed '/^test/a---->this is a example2' example 在test开头的行下,添加一行新的文本“----> ...
- kafka AdminClient 闲时关闭连接
AdminClient 类提供了创建.删除 topic 的 api. 在项目中创建了一个 AdminClient 对象,每次创建 topic 时,调用 org.apache.kafka.clients ...
- 老版本db2这里下
https://www-01.ibm.com/support/docview.wss?uid=swg27007053 db2 10.5.10.1.9.x等 下最新FIX版即可
- springboot国际化
Session方式的国际化/** * @descripte 请求中如果有{@Param lang},则按照lang的格式国际化 * @descripte 请求中如果无{@Param lang},但se ...
- week7
catalog 1.面向对象 2.类的继承(续):直接继承与间接继承 3.类方法.静态方法.属性方法 4.getitem 5.反射 6._new_\_metaclass_ 7.异常处理 1.面向对象 ...
- java接口特性
java接口特性 (1)接口可以被实例化 ,常作为类型使用 (2)实现类必须实现接口的所有方法 ,抽象类除外 (3)实现类可以实现多个几口 java中的多继承 (4)接口中的变量都是静态变量
- java类的理解和相关问题
---java抽象类 当我们定义的对象无法抽象或者不适合抽象为一个具体的类的时候 我们通常定义其为一个抽象类 like 衣服 (多种衣服) 手机 (多种手机) ---接口和抽象类的异同 对于概念上来说 ...
- Oracle 使用序列实现自增列 及重置序列
序列是oracle用来生产一组等间隔的数值.序列是递增,而且连续的.oracle主键没有自增类型,所以一般使用序列产生的值作为某张表的主键,实现主键自增.序列的编号不是在插入记录的时候自动生成的,必须 ...