1高并发服务器:多进程服务器



1多进程并发服务器

使用多进程并发服务器时要考虑以下几点:

A.父最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符)

B.系统内创建进程个数(和内存大小相关)

C.进程创建过多是否降低整体服务性能(进程调度)

2.案例说明

server.c,代码如下:

#include <stdio.h>

#include <string.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <signal.h>

#include <sys/wait.h>

#include <sys/types.h>

#include <arpa/inet.h>

#include <ctype.h>

#include <unistd.h>

#include "wrap.h"

 

#define MAXLINE 80

#define SERV_PORT 8000

 

void do_sigchild(int num) {

   
waitpid(0,NULL,WNOHANG);

}

 

int main(void) {

   
struct sockaddr_in servaddr,cliaddr;

   
socklen_t cliaddr_len;

   
int listenfd,connfd;

   
char buf[MAXLINE];

   
//INET_ADDRSTRLEN是ip地址的最大长度,是系统定义的一个宏

   
char str[INET_ADDRSTRLEN];

   
int i,n;

   
pid_t pid;

 

   
struct sigaction newact;

   
newact.sa_handler = do_sigchild;

   
sigemptyset(&newact.sa_mask);

   
newact.sa_flags = 0;

   
//发信号

   
sigaction(SIGCHLD,&newact,NULL);

 

   
//1.这里建立一个TCP的连接,因为是SOCK_STREAM的,表示的是TCP的

   
listenfd = Socket(AF_INET,SOCK_STREAM,0);

   
//将seraddr内容清零

   
bzero(&servaddr,sizeof(servaddr));

   
servaddr.sin_family = AF_INET;

   
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

   
servaddr.sin_port = htons(SERV_PORT);

   
//2.绑定ip地址和端口号

   
Bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

   
//监听,最多的可以是20个

   
Listen(listenfd,20);

   

   
printf("Accepting connections...\n");

   
while(1) {

       
cliaddr_len = sizeof(cliaddr_len);

       
//connfd:这里才是后续进程需要用的文件描述符

       
//listenfd:已经不用里,可以被销毁,这个程序是在子进程里面销毁

       
connfd = Accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len);

 

       
pid = fork();

       
if(pid ==0) {

           
if(pid == 0) {

               
Close(listenfd);

               
while(1) {

                   
n = Read(connfd,buf,MAXLINE);

                   
if(n == 0) {

                 
      printf("the other side has been closed.\n");

                       
break;

                   
}

                   
printf("received from %s at PORT %d\n",

                       
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,str,sizeof(str)),

      
                 ntohs(cliaddr.sin_port));

                   

                   
for(i = 0; i< n; i++) {

                       
buf[i] = toupper(buf[i]);

                   
}

                   
Write(connfd,buf,n);

               
}

               
Close(connfd);

               
return 0;

           
} else if(pid > 0) {

               
Close(connfd);

           
} else {

               
perr_exit("fork");

           
}

       
}

   
}

}

client.c

#include <stdio.h>

#include <string.h>

#include <unistd.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include "wrap.h"

 

#define MAXLINE 80

#define SERV_PORT 8000

 

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

   
struct sockaddr_in servaddr;

   
char buf[MAXLINE];

   
int sockfd,n;

 

   
sockfd = Socket(AF_INET,SOCK_STREAM,0);

 

   
bzero(&servaddr,sizeof(servaddr));

   
servaddr.sin_family = AF_INET;

   
inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr.s_addr);

   
servaddr.sin_port = htons(SERV_PORT);

 

   
Connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));

 

   
while(fgets(buf,MAXLINE,stdin) != NULL) {

       
Write(sockfd,buf,strlen(buf));

       
n = Read(sockfd,buf,MAXLINE);

       
if(n == 0) {

           
printf("the other side has ben closed.\n");

       
} else {

           
Write(STDOUT_FILENO,buf,n);

       
}

   
}

 

   
Close(sockfd);

   
return 0;

}

wrap.h

#ifndef __WRAP_H_

#define __WRAP_H_

 

void perr_exit(const char *s);

int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);

void Bind(int fd, const struct sockaddr *sa, socklen_t salen);

void Connect(int fd, const struct sockaddr *sa, socklen_t salen);

void Listen(int fd, int backlog);

int Socket(int family, int type, int protocol);

ssize_t Read(int fd, void *ptr, size_t nbytes);

ssize_t Write(int fd, const void *ptr, size_t nbytes);

void Close(int fd);

ssize_t Readn(int fd, void *vptr, size_t n);

ssize_t Writen(int fd, const void *vptr, size_t n);

static ssize_t my_read(int fd, char *ptr);

ssize_t Readline(int fd, void *vptr, size_t maxlen);

 

#endif

wrap.c

#include <stdlib.h>

#include <errno.h>

#include <sys/socket.h>

 

void perr_exit(const char *s)

{

        
perror(s);

        
exit(1);

}

 

int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)

{

        
int n;

 

again:

        
if ( (n = accept(fd, sa, salenptr)) < 0) {

                  
if ((errno == ECONNABORTED) || (errno == EINTR))

                           
goto again;

                  
else

                           
perr_exit("accept error");

        
}

        
return n;

}

 

void Bind(int fd, const struct sockaddr *sa, socklen_t salen)

{

        
if (bind(fd, sa, salen) < 0)

                  
perr_exit("bind error");

}

 

void Connect(int fd, const struct sockaddr *sa, socklen_t salen)

{

        
if (connect(fd, sa, salen) < 0)

                  
perr_exit("connect error");

}

 

void Listen(int fd, int backlog)

{

        
if (listen(fd, backlog) < 0)

                  
perr_exit("listen error");

}

 

int Socket(int family, int type, int protocol)

{

        
int n;

 

        
if ( (n = socket(family, type, protocol)) < 0)

                  
perr_exit("socket error");

        
return n;

}

 

ssize_t Read(int fd, void *ptr, size_t nbytes)

{

        
ssize_t n;

 

again:

        
if ( (n = read(fd, ptr, nbytes)) == -1) {

                  
if (errno == EINTR)

                           
goto again;

                  
else

                           
return -1;

        
}

        
return n;

}

 

ssize_t Write(int fd, const void *ptr, size_t nbytes)

{

        
ssize_t n;

 

again:

        
if ( (n = write(fd, ptr, nbytes)) == -1) {

                  
if (errno == EINTR)

                           
goto again;

                  
else

                           
return -1;

        
}

        
return n;

}

 

void Close(int fd)

{

        
if (close(fd) == -1)

                  
perr_exit("close error");

}

ssize_t Readn(int fd, void *vptr, size_t n)

{

        
size_t  nleft;

        
ssize_t nread;

        
char   *ptr;

 

        
ptr = vptr;

        
nleft = n;

        
while (nleft > 0) {

                  
if ( (nread = read(fd, ptr, nleft)) < 0) {

                           
if (errno == EINTR)

        
                            nread = 0;

                           
else

                                    
return -1;

                  
} else if (nread == 0)

                           
break;

 

                  
nleft -= nread;

                  
ptr += nread;

        
}

        
return n - nleft;

}

 

ssize_t Writen(int fd, const void *vptr, size_t n)

{

        
size_t nleft;

        
ssize_t nwritten;

        
const char *ptr;

 

        
ptr = vptr;

        
nleft = n;

        
while (nleft > 0) {

                  
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {

                           
if (nwritten < 0 && errno == EINTR)

                                    
nwritten = 0;

                           
else

                                    
return -1;

                  
}

 

                  
nleft -= nwritten;

                  
ptr += nwritten;

        
}

        
return n;

}

static ssize_t my_read(int fd, char *ptr)

{

        
static int read_cnt;

        
static char *read_ptr;

        
static char read_buf[100];

 

        
if (read_cnt <= 0) {

again:

                  
if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {

                           
if (errno == EINTR)

                                    
goto again;

                           
return -1;

                  
} else if (read_cnt == 0)

                           
return 0;

                  
read_ptr = read_buf;

        
}

        
read_cnt--;

        
*ptr = *read_ptr++;

        
return 1;

}

 

ssize_t Readline(int fd, void *vptr, size_t maxlen)

{

        
ssize_t n, rc;

        
char    c, *ptr;

 

        
ptr = vptr;

        
for (n = 1; n < maxlen; n++) {

                  
if ( (rc = my_read(fd, &c)) == 1) {

                           
*ptr++ = c;

                           
if (c  == '\n')

                                    
break;

                  
} else if (rc == 0) {

                           
*ptr = 0;

                           
return n - 1;

                  
} else {

                           
return -1;

       
}

        
}

        
*ptr  = 0;

        
return n;

}

运行结果(编译server):

运行client端

 

 

 

 

 

时间: 2025-01-01 23:47:03

1高并发服务器:多进程服务器的相关文章

修改Linux内核参数提高Nginx服务器在高并发时的性能

并发 Linux下高并发的Nginx服务器,当TCP TIME_WAIT套接字数量经常达到两.三万,服务器很容易被拖死.通过修改Linux内核参数,可以减少Nginx服务器的TIME_WAIT套接字数量. vi /etc/sysctl.conf 增加以下几行: 引用 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse =

请问,有没有支持高并发的Java爬虫服务器????

问题描述 请问,有没有支持高并发的Java爬虫服务器???? 请问,有没有支持高并发的爬虫服务器.... 目前想实现支持一个高并发的爬虫.. 解决方案 你应该说的是开源的爬虫框架吧,可以看看这个: nutch 另外,C++的larbin也不错

电商那些年,我摸爬打滚出的高并发架构实战精髓

一.关于高并发   高并发是指在同一个时间点,有很多用户同时访问URL地址,比如:淘宝的双11.双12,就会产生高并发.又如贴吧的爆吧,就是恶意的高并发请求,也就是DDOS攻击,再屌丝点的说法就像玩LOL被ADC暴击了一样,那伤害你懂的.   1 高并发会来带的后果  服务端:导致站点服务器/DB服务器资源被占满崩溃,数据的存储和更新结果和理想的设计是不一样的,比如:出现重复的数据记录,多次添加了用户积分等. 用户角度:尼玛,这么卡,老子来参加活动的,刷新了还是这样,垃圾网站,再也不来了! 我的

优秀开源项目之三:高性能、高并发、高扩展性和可读性的网络服务器架构State Threads

译文在后面. State Threads for Internet Applications Introduction State Threads is an application library which provides a foundation for writing fast and highly scalable Internet Applications on UNIX-like platforms. It combines the simplicity of the multi

支持高并发的IIS Web服务器的常用设置

适用的IIS版本:IIS 7.0, IIS 7.5, IIS 8.0 适用的Windows版本:Windows Server 2008, Windows Server 2008 R2, Windows Server 2012 1.应用程序池(Application Pool)的设置: General->Queue Length设置为65535(队列长度所支持的最大值)    Process Model->Idle Time-out设置为0(不让应用程序池因为没有请求而回收)    Recycl

高并发服务器的设计之架构与瓶颈的设计

做架构设计,难免有时候被人问及系统的瓶颈在哪,那首先来了解下什么是瓶颈? 打个形象 的比方,人的嘴巴可以吞下一整个面包,但是却咽不下去,因为食管不给力,它比较细,所以嘴巴能吞 下的食物大小要受到食管的粗细限制. 城市内部每天会产生几十万件跨城快递,可是跨城的交 通不给力,只允许走小型卡车,一卡车一次就能装几千件,一天下来也不一定能投送的完. 人 在一定时间内能咽下多少食物,货运公司在一天运送多少货物,物理上叫做吞吐量,系统整体的吞吐量 等于最小区域的吞吐量. 下面这张图能够反映: 土黄色管子的流

高并发服务器的设计之内存池的设计

不同的业务,设计也不尽相同,但至少都一些共同的追求,比如性能. 做服务器开发很多年 了,有时候被人问到,服务器性能是什么呢?各种服务器间拼得是什么呢? 简单的回答就是QPS ,并发数,但有时候想想也许也不对. QPS与并发数是针对同样的业务而言的,业务不同,相同 的服务器能承受的压力也会不同. 性能,也许可以打个俗点的比方: 服务器就是一艘船 ,性能就是船的容量,开的速度,行得是否稳当. 该用的用,该省的省.能用内存就别用IO, CPU则能少用就少用,相同的QPS,CPU和内存用的少点的性能就要

高并发服务器的设计之连接池的设计

高并发服务器需要有一些池的设计,如内存池,连接池,数据库连接池. 池(pool)的设计 主要考虑到一些资源的频繁申请和释放,尤其是在高并发的服务器中,几万甚至几十万并发每秒,设计 人员不得不去考虑这些. 比如数据库连接池(sql pool),是通过TCP来通信的,属于IO类,有 一定的延时,在高并发系统中频繁的创建会严重影响系统性能. 内存( mem )的分配是要涉及锁 ( mutex )的,有锁就会有延时,因此可以在开始申请一大块内存,后面进行分配与释放,来节省锁开 销. 服务器的连接处理不仅

通过openresty和嵌入式的lua脚本,来搭建高并发的日志采集服务器

通过openresty和嵌入式的lua脚本,来搭建高并发的日志采集服务器,现在主要采集pc端和app端的日志,数据存储在kafka openresty 服务搭建步骤(mac,linux) wget https://www.openssl.org/source/openssl-1.0.2f.tar.gz tar -zvxf openssl-1.0.2f.tar.gz wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.

请大侠看看用UdpClient做服务器实现高并发的思路

问题描述 小弟最近项目需要,要做个类似于P2P架构的服务器来登记客户端IP和端口实现打洞.因为客户端数据量大概有三千个,所以要求服务器能撑住三千个并发(因为有心跳机制).因为从没做过socket开发,加上网上的UDP资料也讲得不够深入,所以小弟将实现思路写出来请各路大侠帮忙看看是否合理.先讲个小插曲,小弟曾以为异步就是并发,所以用udpclient一下子BeginReceive了三次,以为这样就能一下子处理三个客户端发来的数据.测试时故意让第一次回调先sleep10秒再EndReceive.测试