日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/9/27 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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_ADDRSTRLENip地址的最大長度,是系統定義的一個宏

??? 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

?

?

?

?

?

總結

以上是生活随笔為你收集整理的1高并发服务器:多进程服务器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲欧美激情图片 | 一级在线看 | 五月婷婷激情四射 | 波多野结衣中文字幕在线播放 | 99热99re6国产在线播放 | a级免费视频 | 日本www高清视频 | 伊人网色 | 天堂av在线中文 | 妖精视频一区二区三区 | 五月激情六月婷婷 | 色8久久 | 亚洲午夜色 | a级小视频 | 懂色aⅴ国产一区二区三区 亚洲欧美国产另类 | 欧美日韩1区2区3区 亚洲日本精品视频 | a级大片在线观看 | av一级免费 | 婷婷色视频 | 国产伦精品一区二区三区免费 | 免费插插视频 | 色偷偷综合 | 琪琪射 | 亚洲午夜在线视频 | 亚洲h在线观看 | 神宫寺奈绪一区二区三区 | 在线黄色网 | 午夜视频欧美 | 亚洲乱码一区二区三区在线观看 | 国产富婆一级全黄大片 | 免费污片网站 | 第一宅男av导航入口 | 热久久av | 一区二区三区www | 中文无码精品一区二区三区 | 夜夜爽夜夜叫夜夜高潮漏水 | 爱爱视频免费看 | 91一二区 | 午夜影院色 | 少妇中文字幕 | 无码国产精品一区二区高潮 | 国产av国片偷人妻麻豆 | av在线手机观看 | 国产18页| 久久爱伊人 | 久久午夜鲁丝 | 日本中文字幕观看 | 99中文字幕 | 好吊操这里只有精品 | 亚州av成人 | 男生坤坤放进女生坤坤里 | 欧美黑人多人双交 | 丁香六月在线 | 99re在线| 少妇人妻在线视频 | 手机看片欧美 | 91福利一区 | 黄色大片在线 | 亚洲人成电影一区二区在线 | 三级欧美韩日大片在线看 | 久操免费在线视频 | 日韩精品导航 | www四虎精品视频免费网站 | 成人91免费 | 青青草视频在线观看 | 国产一区在线观看免费 | 91视频黄色 | 一直草| 国产一国产精品一级毛片 | 少妇无内裤下蹲露大唇视频 | 精产国品一区二区三区 | 国产欧美日韩二区 | 青青草原在线免费 | 奇米影视av | 五月天啪啪| 女生扒开尿口让男生桶 | 性色av一区二区三区四区 | 精品视频国产 | 成人免费网站 | 美国av毛片| 日韩精品欧美 | 免费成人一级片 | 免费观看成年人网站 | 日韩成人av网址 | 日本在线三级 | 色播综合网 | 天天干网站 | 夜夜欢视频 | a级片一区二区 | 北条麻妃一区二区三区四区五区 | 欧美刺激性大交 | 久久99精品久久久久婷婷 | 久色免费视频 | 日韩经典第一页 | 欧美熟妇激情一区二区三区 | 欧美日韩高清一区二区三区 | 欧美色射 | 欧美视频网站 | 午夜老司机福利 |