linux解决高并发方法,Linux高并发服务器解决方案

本文探讨了Linux服务器在高并发场景下如何通过epoll技术避免阻塞,提升处理客户端连接的速度。作者详细介绍了TCP连接的四步过程,并展示了如何使用epoll分路技术实现实时响应,以解决15000并发连接问题,优化了服务器性能。
摘要由CSDN通过智能技术生成

Linux高并发服务器案例演示编程

在网络通讯中,咱们经常的服务器常常会受到成千上万的请求提示,而电脑会根据请求创建相对应的socket连接,可是接触过Linux网络编程的人都知道,Linux连接和客户端创建链接,会通过四步(这里以TCP说明)服务器

第一步,建立socket对应的描述符,这里设置好socket的协议类型以及通讯类型(TCP/UDP)网络

#include /* See NOTES */并发

#includedom

int socket(int domain, int type, int protocol);socket

具体的使用方法能够使用man手册查看socket函数函数

第二步,绑定端口,以及相应的ip地址(服务器不用设置)高并发

#include /* See NOTES */性能

#include 测试

intbind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

具体的使用方法能够使用man手册查看bind函数

第三步,监听socket,而且设置最大监听数

#include /* SeeNOTES */

#include

int listen(int sockfd, int backlog);

具体的使用方法能够使用man手册查看listen函数

第四步,接受客户端的链接

#include       /* See NOTES */

#include

int accept(int sockfd, struct sockaddr *addr, socklen_t*addrlen);

具体的使用方法能够使用man手册查看accept函数

注意:

因为上述四步socket创建连接中,accept是阻塞的,意味着若是有不少人同时发出socket请求的时候,服务器只会接收到一少部分的链接,其余都在阻塞队列排队,甚至丢失!甚至创建连接后一旦涉及服务器读写操做时候,涉及到读写,也是会遇到阻塞的!(假设每一个用户链接服务器须要0.1秒,那么10000人链接的话则须要1000秒)这样会让服务器浪费大量时间在阻塞过程,因此咱们要作的,就是尽量的让系统发挥出他的性能,让更多的人可以链接系统,却不用花那么长时间。

具体实现方法:

使用epoll分路技术,让accept不陷入阻塞,当那个客户端发出请求,则处理发出请求的客户端信息,这时候由于客户端发出请求,则一定有读写操做,因此读写操做不用去掉阻塞。

服务器代码:

//模拟接收每一个客户端发来的请求后并往dbg.txt文件写入一个字节

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

void sig_handle(int sig)

{

printf("recv signal :%d\n",sig);

}

int main(int argc, char * argv[])

{

signal(SIGPIPE,sig_handle);

if (argc<2)

{

printf("usage:%s + [count]\n",argv[0]);

return 0;

}

unlink("dbg.txt");

int dbg = open("dbg.txt",O_CREAT|O_APPEND|O_RDWR,0666);

int count = atoi(argv[1]);

int fd = socket(AF_INET,SOCK_STREAM,0);

struct sockaddr_in addr;

memset(&addr,0,sizeof(addr));

addr.sin_family = AF_INET;

addr.sin_port = htons(9988);

int ret = bind(fd,(struct sockaddr*)&addr,sizeof(addr));

if (ret ==-1)

{

perror("bind");

return 0;

}

listen(fd,250);

int is_child_process = 0;//判断在哪一个进程中,父进程0,子进程1

for (int i = 0 ; i < count ; i++)

{

pid_t pid = fork();

if (pid==0)

{

is_child_process = 1;

break;

}

}

struct epoll_event ev;

ev.events = EPOLLIN|EPOLLET;

ev.data.fd = fd;

int epfd = epoll_create(1024);//创建epfd的描述符

int flags = fcntl(fd,F_GETFL);

flags |= O_NONBLOCK;

fcntl(fd,F_SETFL,flags);

epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);

while (1)

{

struct epoll_event evs[10];

int process_count = epoll_wait(epfd,evs,10,5000);

if (process_count == 0) continue;//若是监听的进程都没有事件产生,则再次进入循环,继续监听

for (int i = 0 ; i < process_count ;i++)

{

if (evs[i].data.fd == fd)

{

//当进程中的socket描述符是server的socket自己时候,则accept不然就直接操做

int ret = accept(evs[i].data.fd,NULL,NULL);

if (ret == -1)

{

printf("errno:%s",strerror(errno));

//其余错误,直接exit

break;

}

ev.data.fd = ret;

epoll_ctl(epfd,EPOLL_CTL_ADD,ret,&ev);

}

else

{

//read or write

char buf[1024];

int ret = read(evs[i].data.fd,buf,sizeof(buf));

if (ret == -1)

{

perror("read");

if (errno == EINTR)

break;

exit(0);

}

else if (ret == 0)

{

//normal exit

close(evs[i].data.fd);

break;

}

//printf("recv data %s from pid:%d\n",buf,getpid());

write(dbg,"1",1);

}

}

}

if (!is_child_process)

{

for (int i = 0 ; i < count; i ++)

{

wait(NULL);//等待全部的子进程退出为止

}

}

return 0;

}

测试客户端向服务器发请求代码:

//模拟有20000个客户端同时向服务器发请求

#include

#include

#include

#include

#include

#include

#define PROCESS_COUNT 20000

void func(int argc,char * argv[])

{

int fd =socket(AF_INET,SOCK_STREAM,0);

struct sockaddr_in addr;

addr.sin_family = AF_INET;

addr.sin_port = htons(9988);

addr.sin_addr.s_addr =inet_addr("127.0.0.1");

connect(fd,(structsockaddr*)&addr,sizeof(addr));

if (argc==2)

write(fd,argv[1],strlen(argv[1]));

else

write(fd,"1",1);

char buf[1024];

//recv(fd,buf,sizeof(buf),0);

}

int main(int argc,char *argv[])

{

for (int i = 0 ; i

{

pid_t pid = fork();

if (pid == 0)

{

func(argc,argv);

return 0;

}

}

for (int i = 0 ; i

{

wait(NULL);

}

return 0;

}

结果分析:不一样的电脑测试结果略有不一样,个人客户端定义有20000个同时向服务器发请求,结果处理的请求大概有15500左右,不一样的电脑最高并发数略有不一样。成功的解决了多用户同时向一个服务器发请求的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值