高并发服务器
来源:互联网 发布:好用的洗面奶知乎 编辑:程序博客网 时间:2024/05/18 02:12
多进程并发服务器
使用多进程并发服务器时要考虑以下几点:
1. 父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符)
2. 系统内创建进程个数(与内存大小相关)
3. 进程创建过多是否降低整体服务性能(进程调度)
server
/* 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 "wrap.h"
#define MAXLINE 80
#define SERV_PORT 800
void do_sigchild(intnum)
{
while (waitpid(0, NULL, WNOHANG) > 0)
;
}
int main(void)
{
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
int listenfd, connfd;
char buf[MAXLINE];
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);
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr,sizeof(servaddr));
Listen(listenfd, 20);
printf("Accepting connections ...\n");
while (1) {
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr,&cliaddr_len);
pid = fork();
if (pid == 0) {
Close(listenfd);
while (1) {
n = Read(connfd, buf, MAXLINE);
if (n == 0) {
printf("the other side has beenclosed.\n");
break;
}
printf("received from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_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");
}
Close(listenfd);
return 0;
}
client
/* client.c */
#include <stdio.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include"wrap.h"
#define MAXLINE 80
#define SERV_PORT 6666
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);
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 been closed.\n");
break;
} else
Write(STDOUT_FILENO, buf, n);
}
Close(sockfd);
return 0;
}
多线程并发服务器
在使用线程模型开发服务器时需考虑以下问题:
1. 调整进程内最大文件描述符上限
2. 线程如有共享数据,考虑线程同步
3. 服务于客户端线程退出时,退出处理。(退出值,分离态)
4. 系统负载,随着链接客户端增加,导致其它线程不能及时得到CPU
server
/* server.c */
#include <stdio.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#include"wrap.h"
#define MAXLINE 80
#define SERV_PORT 6666
struct s_info {
struct sockaddr_in cliaddr;
int connfd;
};
void *do_work(void *arg)
{
int n,i;
struct s_info *ts = (struct s_info*)arg;
char buf[MAXLINE];
char str[INET_ADDRSTRLEN];
/*可以在创建线程前设置线程创建属性,设为分离态,哪种效率高内? */
pthread_detach(pthread_self());
while (1) {
n = Read(ts->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,&(*ts).cliaddr.sin_addr, str, sizeof(str)),
ntohs((*ts).cliaddr.sin_port));
for (i = 0; i < n; i++)
buf[i] = toupper(buf[i]);
Write(ts->connfd, buf, n);
}
Close(ts->connfd);
}
int main(void)
{
struct sockaddr_in servaddr, cliaddr;
socklen_t cliaddr_len;
int listenfd, connfd;
int i = 0;
pthread_t tid;
struct s_info ts[256];
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
Bind(listenfd, (struct sockaddr *)&servaddr,sizeof(servaddr));
Listen(listenfd, 20);
printf("Accepting connections ...\n");
while (1) {
cliaddr_len =sizeof(cliaddr);
connfd =Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);
ts[i].cliaddr = cliaddr;
ts[i].connfd = connfd;
/*达到线程最大数时,pthread_create出错处理,增加服务器稳定性 */
pthread_create(&tid,NULL, do_work, (void*)&ts[i]);
i++;
}
return 0;
}
client
/* client.c */
#include <stdio.h>
#include <string.h>
#include<unistd.h>
#include<netinet/in.h>
#include"wrap.h"
#define MAXLINE 80
#define SERV_PORT 6666
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);
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 been closed.\n");
else
Write(STDOUT_FILENO, buf, n);
}
Close(sockfd);
return 0;
}
- 高并发服务器博客
- 高并发服务器支持
- 高并发服务器架构
- 高并发服务器
- 高并发服务器处理
- 服务器高并发
- 高并发服务器
- 高并发服务器设计
- 高并发服务器
- 服务器高并发优化
- 高并发服务器
- 高并发服务器实现策略
- Epoll实现服务器高并发
- 多线程高并发服务器相关
- Nginx架构高并发服务器
- epoll实现服务器高并发
- 高并发计算服务器数量
- Linux高并发服务器解决方案
- webdriver.chrome()禁止加载图片
- 计算圆,正方形和长方形的面积
- C开发笔试题三道
- 算法分析与设计week04--55.Jump Game
- XML
- 高并发服务器
- MFC框架界面开发(五):基于文档模板架构的软件
- Servlet知识
- Codeforce 101581 problem C 【gcd+预处理】
- java小程序——八皇后
- 集合之间的操作util-在全集allSet中标识出在子集sonSet 出现过的元素
- libmaxminddb
- [复习]进制转换 十进制转任意进制&任意进制转十进制
- 整数划分