}
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 nbytes) { }
int Close(int fd) {
int n; ssize_t n;
if ( (n = write(fd, ptr, nbytes)) == -1) { }
return n;
if (errno == EINTR)
goto again; return -1; else
again:
ssize_t n;
if ( (n = read(fd, ptr, nbytes)) == -1) { }
return n;
if (errno == EINTR)
goto again; return -1; else
again:
int n;
if ( (n = socket(family, type, protocol)) < 0)
perr_exit(\return n; int n;
if ((n = listen(fd, backlog))< 0)
perr_exit(\return n; int n;
if ((n = connect(fd, sa, salen))< 0)
perr_exit(\return n;
}
if ((n = close(fd)) == -1)
perr_exit(\return n;
ssize_t Readn(int fd, void *vptr, size_t n) { }
ssize_t Writen(int fd, const void *vptr, size_t n) { }
while (nleft > 0) { }
return n;
if ( (nwritten = write(fd, ptr, nleft)) <= 0) { }
nleft -= nwritten; ptr += nwritten;
if (nwritten < 0 && errno == EINTR)
nwritten = 0; return -1; else
ptr = vptr; nleft = n; size_t nleft; ssize_t nwritten; const char *ptr; while (nleft > 0) { }
return n - nleft;
if ( (nread = read(fd, ptr, nleft)) < 0) {
if (errno == EINTR)
nread = 0; return -1; else
ptr = vptr; nleft = n; size_t nleft; ssize_t nread; char *ptr;
} else if (nread == 0)
break; nleft -= nread; ptr += nread;
static ssize_t my_read(int fd, char *ptr) { }
ssize_t Readline(int fd, void *vptr, size_t maxlen) { }
for (n = 1; n < maxlen; n++) { }
*ptr = 0; return n;
if ( (rc = my_read(fd, &c)) == 1) {
*ptr++ = c; if (c == '\\n')
break;
ssize_t n, rc; char c, *ptr; ptr = vptr;
if (read_cnt <= 0) { }
read_cnt--;
*ptr = *read_ptr++; return 1;
if ((read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) {
if (errno == EINTR)
goto again; return -1; return 0;
again:
static int read_cnt; static char *read_ptr; static char read_buf[100];
} else if (read_cnt == 0) read_ptr = read_buf;
} else if (rc == 0) {
*ptr = 0; return n - 1; return -1;
} else
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 nbytes); int Close(int fd);
ssize_t Readn(int fd, void *vptr, size_t n);
ssize_t Writen(int fd, const void *vptr, size_t n); ssize_t my_read(int fd, char *ptr);
ssize_t Readline(int fd, void *vptr, size_t maxlen); #endif
高并发服务器
多进程并发服务器
使用多进程并发服务器时要考虑以下几点:
1. 父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 2. 系统内创建进程个数(与内存大小相关) 3. 进程创建过多是否降低整体服务性能(进程调度)
server
/* server.c */ #include
#include
#define MAXLINE 80 #define SERV_PORT 800
void do_sigchild(int num) { }
int main(void) {
pid = fork(); if (pid == 0) {
Close(listenfd); while (1) {
n = Read(connfd, buf, MAXLINE);
printf(\while (1) {
cliaddr_len = sizeof(cliaddr);
connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); Listen(listenfd, 20);
Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT); listenfd = Socket(AF_INET, SOCK_STREAM, 0); struct sigaction newact;
newact.sa_handler = do_sigchild; sigemptyset(&newact.sa_mask); newact.sa_flags = 0;
sigaction(SIGCHLD, &newact, NULL); 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;
while (waitpid(0, NULL, WNOHANG) > 0)
;