Chinaunix首页 | 论坛 | 博客
  • 博客访问: 180433
  • 博文数量: 38
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 346
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-04 00:06
文章分类

全部博文(38)

文章存档

2016年(3)

2015年(15)

2014年(16)

2013年(4)

我的朋友

分类: LINUX

2013-12-14 22:41:34

   
    TCP服务器老师平时教我们写过,现在学习ARM,接触硬件的时候了,感觉网络编程渐渐远去了,特地写写回顾一下所学知识。
    其方法就是将回射服务器改写成并发的,问题就在于要创建子进程,而且是循环创建子进程,与多个客户端建立好连接后让子进程完成数据的收发。


    head.h
    
受老师的影响,头文件习惯放在/usr/include/目录下

点击(此处)折叠或打开

  1. #ifndef _HEAD_H_
  2. #define _HEAD_H_ 1

  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <errno.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #include <pthread.h>
  12. #include <semaphore.h>
  13. #include <signal.h>
  14. #include <sys/ipc.h>
  15. #include <sys/shm.h>
  16. #include <dirent.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <sys/socket.h>

  20. #define handler_error(msg)     do{\
  21.     perror(msg);exit(EXIT_FAILURE);}while(0) /*just do once*/
  22.     

  23. #endif

    server.c

点击(此处)折叠或打开

  1. #include <head.h>

  2. #define handler_error(msg) do{\
  3.     perror(msg);exit(EXIT_FAILURE);}while(0)

  4. void handler(int signum)//信号处理函数
  5. {
  6.     waitpid(-1,NULL,WNOHANG);
  7.     return;
  8. }


  9. int do_client(int sockfd)
  10. {
  11.     int n;
  12.     char buf[1024];
  13.     
  14.     while(1)
  15.     {
  16.         //接受数据
  17.         n = read(sockfd,buf,sizeof(buf) - 1);
  18.         buf[n] = '\0';

  19.         printf("Recv %d bytes : %s.\n",n,buf);

  20.         //发回去
  21.         write(sockfd,buf,n);
  22.         
  23.         if(strncmp(buf,"quit",4) == 0)
  24.             break;

  25.     }

  26.     return 0;
  27. }


  28. //./server ip port
  29. int main(int argc, const char *argv[])
  30. {
  31.     int connect_fd,pid;
  32.     struct sockaddr_in peer_addr;
  33.     socklen_t addrlen = sizeof(struct sockaddr);
  34.     int listen_fd;
  35.     struct sockaddr_in server_addr;
  36.     
  37.     if(argc < 3)
  38.     {
  39.         fprintf(stderr,"Usage : %s ip port.\n",argv[1]);
  40.         exit(EXIT_FAILURE);
  41.     }

  42.     if(signal(SIGCHLD,handler) == SIG_ERR)
  43.     {
  44.         handler_error("signal");
  45.     }
  46.   
  47.      listen_fd = socket(AF_INET,SOCK_STREAM,0);
  48.      if(listen_fd < 0){
  49.          handler_error("socket");
  50.      }

  51.      memset(&server_addr,0,sizeof(server_addr));
  52.      server_addr.sin_family = AF_INET;
  53.      server_addr.sin_port = htons(atoi(argv[2]));
  54.      server_addr.sin_addr.s_addr = inet_addr(argv[1]);

  55.      //绑定地址
  56.      if(bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
  57.      {
  58.          handler_error("bind");
  59.      }
  60.     
  61.      //设置socket为监听状态
  62.      listen(listen_fd,5);

  63.      printf("listen ...\n");
  64.     
  65.      while(1)
  66.      {    
  67.          
  68.         connect_fd = accept(listen_fd,(struct sockaddr *)&peer_addr,&addrlen);
  69.         if(connect_fd < 0)
  70.             handler_error("accept");
  71.         
  72.         printf("*****************************\n");
  73.         printf("Peer Ip :%s.\n",inet_ntoa(peer_addr.sin_addr));
  74.         printf("Peer Port:%d.\n",ntohs(peer_addr.sin_port));
  75.         printf("*****************************\n");
  76.         
  77.         //创建子进程和客户端进行收发数据
  78.         pid = fork();
  79.         if(pid < 0){
  80.             handler_error("fork");
  81.         }

  82.         if(pid == 0)
  83.         {
  84.             do_client(connect_fd);
  85.             exit(EXIT_FAILURE);
  86.         }

  87.         //避免父进程fd浪费
  88.         close(connect_fd);
  89.      }

  90.     return 0;
  91. }
    client.c

点击(此处)折叠或打开

  1. #include <head.h>

  2. //./client ip port
  3. int main(int argc, const char *argv[])
  4. {
  5.     int n;
  6.     char buf[1024];
  7.     int sockfd;
  8.     struct sockaddr_in server_addr;

  9.     //创建流式socket
  10.     sockfd = socket(AF_INET,SOCK_STREAM,0);
  11.     if(sockfd < 0){
  12.         handler_error("socket");
  13.     }

  14.     memset(&server_addr,0,sizeof(server_addr));
  15.     server_addr.sin_family = AF_INET;
  16.     server_addr.sin_port = htons(atoi(argv[2]));
  17.     server_addr.sin_addr.s_addr = inet_addr(argv[1]);

  18.     //int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
  19.     if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0){
  20.         handler_error("connect");
  21.     }
  22.     
  23.     //connect成功返回,表示三次握手完成
  24.     while(1)
  25.     {
  26.         printf(">");

  27.         fgets(buf,sizeof(buf),stdin);
  28.         buf[strlen(buf) - 1] = '\0';

  29.         write(sockfd,buf,strlen(buf));


  30.         memset(buf,0,sizeof(buf));
  31.         n = read(sockfd,buf,sizeof(buf) - 1);
  32.         buf[n] = '\0';
  33.         
  34.         printf("Recv %d bytes : %s.\n",n,buf);
  35.     }

  36.     return 0;
  37. }
    截图效果:
阅读(1939) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~