标签:
/************************************************************************* > File Name: server4.c > Description: server4.c > Author: Liubingbing > Created Time: 2015年07月25日 星期六 17时22分52秒 > Other: server4.c ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <signal.h> int main() { int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; /* socket函数创建套接字 */ server_sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 套接字地址由结构sockaddr_in来指定,一个AF_INET套接字由它的域,IP地址和端口号完全确定 */ server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = htonl(INADDR_ANY); server_address.sin_port = htons(9734); server_len = sizeof(server_address); /* bind函数给套接字命名,使AF_INET套接字关联到一个IP端口号 * 此外bind调用需要就爱那个一个特定的地址结构转换为指向通用地址类型(struct sockaddr *) */ bind(server_sockfd, (struct sockaddr *)&server_address, server_len); /* 创建一个连接队列,忽略子进程的退出细节,等待客户的到来 */ listen(server_sockfd, 5); signal(SIGCHLD, SIG_IGN); while (1) { char ch; printf("server waiting\n"); /* 接受连接 */ client_len = sizeof(client_address); client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len); /* 通过fork调用为这个客户创建一个子进程,然后测试在父进程还是子进程 */ if (fork() == 0) { read(client_sockfd, &ch, 1); sleep(5); ch++; write(client_sockfd, &ch, 1); close(client_sockfd); exit(0); } else { close(client_sockfd); } } }在处理客户请求时插入的5秒延迟是为了模拟服务器的计算时间或数据库访问时间.如果在前面的服务器中这样做,client3的每次运行都将花费5秒钟的时间,而新服务器可以同时处理多个client3程序,所花费的总时间将只有5秒钟多一点.如下所示:
#include <sys/types.h> #include <sys/time.h> void FD_ZERO(fd_set *fdset); void FD_CLR(int fd, fd_set *fdset); void FD_SET(int fd, fd_set *fdset); void FD_ISSET(int fd, fd_set *fdset);FD_ZERO用于将fd_set初始化为空集合.
struct timeval { time_t tv_sec; /* seconds */ long tv_usec; /* microseconds */ };类型time_t在头文件sys/types.h中被定义为一个整数类型.
#include <sys/types.h> #include <sys/time.h> int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *timeout);select调用用于测试文件描述符集合中,是否有一个文件描述符已处于可读状态或可写状态或错误状态,它将阻塞以等待某个文件描述符进入上述这些状态.
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/yiranant/article/details/47061785