1、简介
主进程运行时,等待客户端连接的到来,当客户端连接请求到来时,服务器的accept()函数成功返回,此时服务器端进行进程分叉,父进程继续等待客户端的连接请求;而子进程则处理客户端的业务请求,接收客户端的数据,分析数据并返回结果。
2、tcp模型
3、服务器源代码(concurrency-server3.c):
- #include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <errno.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <netinet/in.h>
-
#include <sys/types.h>
-
#include <unistd.h>
-
#include <time.h>
-
-
#define BUFLEN 1024
-
-
/*******************并发服务器模型之三:单客户端单进程,统一accept**********************/
-
-
static void handle_request(int newfd){
-
char buf[BUFLEN];
-
int len;
-
time_t now;
-
/******处理客户端请求*******/
-
bzero(buf,BUFLEN);
-
len = recv(newfd,buf,BUFLEN,0);
-
if(len >0 && !strncmp(buf,"TIME",4)){
-
bzero(buf,BUFLEN);
-
/*获取系统当前时间*/
-
now = time(NULL);
-
/*ctime将系统时间转换为字符串,sprintf使转化后的字符串保存在buf*/
-
sprintf(buf,"%24s\r\n",ctime(&now));
-
//******发送系统时间*******/
-
send(newfd,buf,strlen(buf),0);
-
}
-
/*关闭通讯的套接字*/
-
close(newfd);
-
}
-
-
static void handle_connect(int sockfd){
-
int newfd;
-
struct sockaddr_in c_addr;
-
socklen_t len;
-
-
while(1){
-
len = sizeof(struct sockaddr);
-
if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) == -1){
-
perror("accept");
-
exit(errno);
-
}else{
-
/*创建进程来处理连接*/
-
if(fork() > 0)
-
close(newfd);
-
else{
-
printf("\n*****************通信开始***************\n");
-
printf("正在与您通信的客户端是:%s: %d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
-
handle_request(newfd);
-
}
-
}
-
}
-
}
-
-
int main(int argc, char **argv)
-
{
-
int sockfd;
-
struct sockaddr_in s_addr;
-
unsigned int port, listnum;
-
-
/*建立socket*/
-
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
-
perror("socket");
-
exit(errno);
-
}else
-
printf("socket create success!\n");
-
/*设置服务器端口*/
-
if(argv[2])
-
port = atoi(argv[2]);
-
else
-
port = 4567;
-
/*设置侦听队列长度*/
-
if(argv[3])
-
listnum = atoi(argv[3]);
-
else
-
listnum = 3;
-
/*设置服务器ip*/
-
bzero(&s_addr, sizeof(s_addr));
-
s_addr.sin_family = AF_INET;
-
s_addr.sin_port = htons(port);
-
if(argv[1])
-
s_addr.sin_addr.s_addr = inet_addr(argv[1]);
-
else
-
s_addr.sin_addr.s_addr = INADDR_ANY;
-
/*把地址和端口帮定到套接字上*/
-
if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){
-
perror("bind");
-
exit(errno);
-
}else
-
printf("bind success!\n");
-
/*侦听本地端口*/
-
if(listen(sockfd,listnum) == -1){
-
perror("listen");
-
exit(errno);
-
}else
-
printf("the server is listening!\n");
-
/*处理客户端的连接*/
-
handle_connect(sockfd);
-
/*关闭服务器的套接字*/
-
close(sockfd);
-
return 0;
-
}
4、客户端源代码(concurrency-client.c)与之前的一样。
5、编译源代码:
new@new-desktop:~/linux/c$ gcc -Wall concurrency-server3.c -o server
new@new-desktop:~/linux/c$ gcc -Wall concurrency-client.c -o client
6、运行,试试吧
阅读(2069) | 评论(0) | 转发(1) |