C语言使用多进程实现高并发tcp服务器
多进程并发服务器的流程
- socket; 创建监听套接字
- bind; 绑定地址结构
- listen(); 设置监听上限
- accept();进行循环监听
- fork();接收到客户端请求创建新的进程
- close(); 与客户端通讯的套接字关闭
实现C语言并发服务器
#include <stdio.h> #include <apra/inet.h> #include <errno.h> #include <sys/socket.h> #include <unistd.h> #include <signal.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; } int Bind(int fd, struct sockaddr *sa, socklen_t salen) { int n; if ((n = bind(fd, sa, salen))<0){ perr_exit("bind error"); } return n; } int Connect(int fd, const struct sockaddr *sa, socklen_t salen) { int n; n = connect(fd, sa, salen); if (n < 0) { perr_exit("connect error"); } return n; } int Listen(int fd, int backlog) { int n; if ((n=listen(fd, backlog))<0) { perr_exit("listen error"); } return n; } 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; } int Close(int fd) { int n; n = close(fd); if (n==-1){ perr_exit("close error"); } return n; } // 读取指定大小的内容 ssize_t Readn(int fd, void *vptr, size_t n) { size_t nleft; //usigned int 剩余未读取的字节数 ssize_t nread; //int 实际读到的字节数 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; } int main(int agrv, char *agrc[]) { int lfd, cfd; pid_t pid; struct sockaddr_in srv_addr, clt_addr; socklen_t clt_addr_len; char buf[BUFSIZ]; int ret,i; memset(&srv_addr, 0, sizeof(srv_addr)); // 将地址结构清0 // bzero(&srv_addr, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; srv_addr.sin_port = htons(7000); srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); lfd = Socket(AF_INET, SOCK_STREAM, 0); Bind(lfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr)); Listen(lfd, 128); clt_addr_len = sizeof(clt_addr); while (1){ cfd = Accept(lfd, (struct sockaddr *)&clt_addr, &clt_addr_len); // 创建子进程 pid = fork(); if (pid < 0) { perr_exit("fork error"); } else if (pid==0){ // 子进程 close(lfd); break; } else{ // 注册信号捕捉 struct sigaction act; act.sa_handler = catch_child; sigemptyset(&act.sa_mask); act.sa_flags = 0; ret = sigaction(SIGCHLD, &act, NULL); if (ret!=0){ perr_exit("sigaction error"); } close(cfd); continue; } } if (pid == 0){ for (;;){ ret = read(cfd, buf, sizeof(buf)); if(ret == 0){ // 检测到客户端关闭了 close(cfd); exit(1); } for (i=0; i<ret; i++){ cout << buf[i] << endl; buf[i] = toupper(buf[i]); } request = buf; cout <<request << endl; write(cfd, buf, ret); write(STDOUT_FILENO, buf, ret); } } }
相关推荐
chensen 2020-11-14
拉斯厄尔高福 2020-11-04
杜倩 2020-10-29
拉斯厄尔高福 2020-10-19
嵌入式资讯精选 2020-10-15
zhaochen00 2020-10-13
penkgao 2020-10-13
yiyilanmei 2020-10-05
wanshiyingg 2020-09-29
Mars的自语 2020-09-27
shenwenjie 2020-09-24
一个逗逗 2020-09-22
flycony 2020-09-13
zhaochen00 2020-08-20
Biao 2020-08-20
qingsongzdq 2020-08-19
penkgao 2020-08-17
cetrolchen 2020-08-14
GuoSir 2020-08-07