多进程并发服务器

知识养成了思想,思想同时又在融化知识。这篇文章主要讲述多进程并发服务器相关的知识,希望能为你提供帮助。
一、多进程程并发服务器

模型
socket();
bind();
listen();
while(1)
accept();
if(fork() == 0)

process();
close();
exit();

close();


二、小写转大写的设计流程1.设计流程
服务器端:       
      父进程一直监听有没有客户端的连接,如果有客户端连接了,就fork()出一个子进程去处理这个连接,而父进程一直监听,一旦有一个新客户端的连接就需要fork()一个新进程。
创建socket()
给套接字命名bind
创建监听上限listen()
第二部分:
while(1)
cfd=accept(); //接收客户端的连接请求
pid=fork(); 创建子进程
if(pid==0)
//进入子进程,子进程需要完成如下事情:
1.子进程无须监听,关闭监听套接字
2.读取客户端发送过来的字母
3.完成小写转大写
4.将转换完成后的大写字母返回给客户端
else if(pid> 0)
//进入父进程
1.父进程无须与客户端建立连接,关闭连接套接字
2.父进程需要回收已经死亡的子进程


客户端:
socket() 创建套接字;
connect() 实现与服务器的通信;
read/recv、write/send9() 与服务器进行通信;
close()关闭套接字

【多进程并发服务器】2.注意事项
  • 父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符)  。
  •   系统内创建进程个数(与内存大小相关)。
  • 父进程不能回收子进程,需要注册信号捕捉函数回收子进程,避免出现僵尸进程。
三、代码实现:小写转换大写(1)server.c
#include < stdio.h>
#include < unistd.h>
#include < stdlib.h>
#include < arpa/inet.h>
#include < ctype.h>
#include < strings.h>
#include < sys/wait.h>

#include "wrap.h"

#define SERV_PORT 8000

void wait_child(int signo)

while (waitpid(0, NULL, WNOHANG) > 0);
//回收子进程
return ;


int main(void)

pid_t pid;
int lfd, cfd;
struct sockaddr_in serv_addr, clie_addr;
socklen_t clie_addr_len;
char buf[BUFSIZ], clie_IP[BUFSIZ];
int n, i;

lfd = Socket(AF_INET, SOCK_STREAM, 0);

bzero(& serv_addr, sizeof(serv_addr)); //将地址结构清零
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(SERV_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(lfd, (struct sockaddr *)& serv_addr, sizeof(serv_addr));
Listen(lfd, 128);

while (1)
clie_addr_len = sizeof(clie_addr);
cfd = Accept(lfd, (struct sockaddr *)& clie_addr, & clie_addr_len);
printf("client IP:%s, port:%d\\n",
inet_ntop(AF_INET, & clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)),
ntohs(clie_addr.sin_port));

pid = fork(); //创建子进程
if (pid < 0)
perr_exit("fork error");
//perror("fork error");
//exit(1);
else if (pid == 0)
close(lfd);
break;
else
close(cfd);
signal(SIGCHLD, wait_child);



if (pid == 0)
//while(1)实现多次写
while (1)
n = Read(cfd, buf, sizeof(buf));
if (n == 0)//client close
close(cfd);
return 0;
else if (n == -1)
perror("read error");
exit(1);
else
for (i = 0; i < n; i++)
buf[i] = toupper(buf[i]);
write(cfd, buf, n);
write(STDOUT_FILENO, buf, n); //写到标准输出,方便查看




return 0;

(2)wrap.h
#ifndef __WRAP_H_
#define __WRAP_H_

void perr_exit(const char *s);
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);
int Bind(int fd, const struct sockaddr *sa, socklen_t salen);
int Connect(int fd, const struct sockaddr *sa, socklen_t salen);
int 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

    推荐阅读