Chinaunix首页 | 论坛 | 博客
  • 博客访问: 578563
  • 博文数量: 65
  • 博客积分: 2844
  • 博客等级: 上尉
  • 技术积分: 996
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-02 12:01
文章分类

全部博文(65)

文章存档

2014年(7)

2012年(20)

2011年(35)

2010年(3)

分类: LINUX

2011-07-12 20:42:26

1、简介

主进程运行时,等待客户端连接的到来,当客户端连接请求到来时,服务器的accept()函数成功返回,此时服务器端进行进程分叉,父进程继续等待客户端的连接请求;而子进程则处理客户端的业务请求,接收客户端的数据,分析数据并返回结果。

2、tcp模型

image

3、服务器源代码(concurrency-server3.c):

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <sys/socket.h>
  6. #include <arpa/inet.h>
  7. #include <netinet/in.h>
  8. #include <sys/types.h>
  9. #include <unistd.h>
  10. #include <time.h>

  11. #define BUFLEN 1024

  12. /*******************并发服务器模型之三:单客户端单进程,统一accept**********************/

  13. static void handle_request(int newfd){
  14.     char buf[BUFLEN];
  15.     int len;
  16.     time_t now;
  17.     /******处理客户端请求*******/
  18.     bzero(buf,BUFLEN);
  19.     len = recv(newfd,buf,BUFLEN,0);
  20.     if(len >0 && !strncmp(buf,"TIME",4)){
  21.         bzero(buf,BUFLEN);
  22.         /*获取系统当前时间*/
  23.         now = time(NULL);
  24.         /*ctime将系统时间转换为字符串,sprintf使转化后的字符串保存在buf*/
  25.         sprintf(buf,"%24s\r\n",ctime(&now));
  26.         //******发送系统时间*******/
  27.         send(newfd,buf,strlen(buf),0);
  28.     }
  29.     /*关闭通讯的套接字*/
  30.     close(newfd);
  31. }

  32. static void handle_connect(int sockfd){
  33.     int newfd;
  34.     struct sockaddr_in c_addr;
  35.     socklen_t len;

  36.     while(1){
  37.         len = sizeof(struct sockaddr);
  38.         if((newfd = accept(sockfd,(struct sockaddr*) &c_addr, &len)) == -1){
  39.             perror("accept");        
  40.             exit(errno);
  41.         }else{
  42.             /*创建进程来处理连接*/
  43.             if(fork() > 0)
  44.                 close(newfd);            
  45.             else{
  46.                 printf("\n*****************通信开始***************\n");
  47.                 printf("正在与您通信的客户端是:%s: %d\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
  48.                 handle_request(newfd);
  49.             }
  50.         }
  51.     }
  52. }

  53. int main(int argc, char **argv)
  54. {
  55.     int sockfd;
  56.     struct sockaddr_in s_addr;
  57.     unsigned int port, listnum;
  58.     
  59.     /*建立socket*/
  60.     if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
  61.         perror("socket");
  62.         exit(errno);
  63.     }else
  64.         printf("socket create success!\n");
  65.     /*设置服务器端口*/    
  66.     if(argv[2])
  67.         port = atoi(argv[2]);
  68.     else
  69.         port = 4567;
  70.     /*设置侦听队列长度*/
  71.     if(argv[3])
  72.         listnum = atoi(argv[3]);
  73.     else
  74.         listnum = 3;
  75.     /*设置服务器ip*/
  76.     bzero(&s_addr, sizeof(s_addr));
  77.     s_addr.sin_family = AF_INET;
  78.     s_addr.sin_port = htons(port);
  79.     if(argv[1])
  80.         s_addr.sin_addr.s_addr = inet_addr(argv[1]);
  81.     else
  82.         s_addr.sin_addr.s_addr = INADDR_ANY;
  83.     /*把地址和端口帮定到套接字上*/
  84.     if((bind(sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1){
  85.         perror("bind");
  86.         exit(errno);
  87.     }else
  88.         printf("bind success!\n");
  89.     /*侦听本地端口*/
  90.     if(listen(sockfd,listnum) == -1){
  91.         perror("listen");
  92.         exit(errno);    
  93.     }else
  94.         printf("the server is listening!\n");
  95.     /*处理客户端的连接*/
  96.     handle_connect(sockfd);
  97.     /*关闭服务器的套接字*/
  98.     close(sockfd);
  99.     return 0;
  100. }

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) |
给主人留下些什么吧!~~