/*************************************************************************
> 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