Linux网络编程:TCP服务器(多进程)

来源:互联网 发布:java实现支付功能 编辑:程序博客网 时间:2024/04/27 15:57

服务器程序:tcp_server.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <strings.h>  
  4. #include <sys/types.h>  
  5. #include <sys/socket.h>  
  6. #include <unistd.h>  
  7. #include <linux/in.h>  
  8. #include <signal.h>  
  9.   
  10. extern void sig_proccess(int signo);  
  11.   
  12. #define BACKLOG 5               /* 侦听队列长度 */  
  13.   
  14. /************************************************* 
  15. * Function    :  
  16. * Description : 服务端主程序 
  17. * Calls       : process_conn_server 
  18. * Called By   :  
  19. * Input       :  
  20. * Output      :  
  21. * Return      :  
  22. *************************************************/  
  23. int main(int argc, char *argv[])  
  24. {  
  25.     if (argc != 2)  
  26.     {  
  27.         printf("Usage:%s port_number\n", argv[0]);  
  28.         return 1;  
  29.     }  
  30.   
  31.     int port;  
  32.     int ss, sc;                 /* ss为服务器的socket描述符,sc为客户端的socket描述符 */  
  33.     struct sockaddr_in server_addr; /* 服务器地址结构 */  
  34.     struct sockaddr_in client_addr; /* 客户端地址结构 */  
  35.     int err;                    /* 返回值 */  
  36.     pid_t pid;                  /* 分叉的进行id */  
  37.   
  38.     signal(SIGINT, sig_proccess);  
  39.     signal(SIGPIPE, sig_proccess);  
  40.   
  41.     /* 建立一个流式套接字 */  
  42.     ss = socket(AF_INET, SOCK_STREAM, 0);  
  43.     if (ss < 0)  
  44.     {                           /* 出错 */  
  45.         printf("socket error\n");  
  46.         return -1;  
  47.     }  
  48.     //获得输入的端口   
  49.     port = atoi(argv[1]);  
  50.   
  51.     /* 设置服务器地址 */  
  52.     bzero(&server_addr, sizeof(server_addr));   /* 清0 */  
  53.     server_addr.sin_family = AF_INET;   /* 协议族 */  
  54.     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);    /* 本地地址 */  
  55.     server_addr.sin_port = htons(port); /* 服务器端口 */  
  56.   
  57.     /* 绑定地址结构到套接字描述符 */  
  58.     err = bind(ss, (struct sockaddr *)&server_addr, sizeof(server_addr));  
  59.     if (err < 0)  
  60.     {                           /* 出错 */  
  61.         printf("bind error\n");  
  62.         return -1;  
  63.     }  
  64.   
  65.     /* 设置侦听 */  
  66.     err = listen(ss, BACKLOG);  
  67.     if (err < 0)  
  68.     {                           /* 出错 */  
  69.         printf("listen error\n");  
  70.         return -1;  
  71.     }  
  72.   
  73.     /* 主循环过程 */  
  74.     for (;;)  
  75.     {  
  76.         int addrlen = sizeof(struct sockaddr);  
  77.         /* 接收客户端连接 */  
  78.         sc = accept(ss, (struct sockaddr *)&client_addr, &addrlen);  
  79.         if (sc < 0)  
  80.         {                       /* 出错 */  
  81.             continue;           /* 结束本次循环 */  
  82.         }  
  83.   
  84.         /* 建立一个新的进程处理到来的连接 */  
  85.         pid = fork();           /* 分叉进程 */  
  86.         if (pid == 0)  
  87.         {                       /* 子进程中 */  
  88.             close(ss);          /* 在子进程中关闭服务器的侦听 */  
  89.             process_conn_server(sc);    /* 处理连接 */  
  90.         }  
  91.         else  
  92.         {  
  93.             close(sc);          /* 在父进程中关闭客户端的连接 */  
  94.         }  
  95.     }  
  96. }  

客户端程序:tcp_client.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <strings.h>  
  4. #include <sys/types.h>  
  5. #include <sys/socket.h>  
  6. #include <unistd.h>  
  7. #include <linux/in.h>  
  8. #include <signal.h>  
  9.   
  10. extern void sig_proccess(int signo);  
  11. extern void sig_pipe(int signo);  
  12. static int s;  
  13. void sig_proccess_client(int signo)  
  14. {  
  15.     printf("Catch a exit signal\n");  
  16.     close(s);  
  17.     exit(0);  
  18. }  
  19.   
  20. /************************************************* 
  21. * Function    :  
  22. * Description : 客户端主程序 
  23. * Calls       : process_conn_client 
  24. * Called By   :  
  25. * Input       :  
  26. * Output      :  
  27. * Return      :  
  28. *************************************************/  
  29. int main(int argc, char *argv[])  
  30. {  
  31.     int port;  
  32.     struct sockaddr_in server_addr; /* 服务器地址结构 */  
  33.     int err;                    /* 返回值 */  
  34.   
  35.     signal(SIGINT, sig_proccess);  
  36.     signal(SIGPIPE, sig_pipe);  
  37.   
  38.     /* 建立一个流式套接字 */  
  39.     s = socket(AF_INET, SOCK_STREAM, 0);  
  40.     if (s < 0)  
  41.     {                           /* 出错 */  
  42.         printf("socket error\n");  
  43.         return -1;  
  44.     }  
  45.   
  46.     /* 将用户输入的字符串类型的IP地址转为整型 */  
  47.     inet_pton(AF_INET, argv[1], &server_addr.sin_addr);  
  48.     port = atoi(argv[2]);  
  49.   
  50.     /* 设置服务器地址 */  
  51.     bzero(&server_addr, sizeof(server_addr));   /* 清0 */  
  52.     server_addr.sin_family = AF_INET;   /* 协议族 */  
  53.     server_addr.sin_addr.s_addr = htonl(INADDR_ANY);    /* 本地地址 */  
  54.     server_addr.sin_port = htons(port); /* 服务器端口 */  
  55.   
  56.     /* 连接服务器 */  
  57.     connect(s, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));  
  58.     process_conn_client(s);     /* 客户端处理过程 */  
  59.     close(s);                   /* 关闭连接 */  
  60. }  

调用程序:tcp_process.c

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <string.h>  
  5. #include <signal.h>  
  6.   
  7. /************************************************* 
  8. * Function    :  
  9. * Description : 服务器对客户端的处理 
  10. * Calls       :  
  11. * Called By   :  
  12. * Input       :  
  13. * Output      :  
  14. * Return      :  
  15. *************************************************/  
  16. void process_conn_server(int s)  
  17. {  
  18.     ssize_t size = 0;  
  19.     char buffer[1024];          /* 数据的缓冲区 */  
  20.   
  21.     for (;;)  
  22.     {                           /* 循环处理过程 */  
  23.         /* 从套接字中读取数据放到缓冲区buffer中 */  
  24.         memset(buffer, '0', 1024);  
  25.         size = read(s, buffer, 1024);  
  26.         if (size == 0)  
  27.         {                       /* 没有数据 */  
  28.             return;  
  29.         }  
  30.         printf("Server: Client had sent %.2d bytes to me!\n", size - 1);  
  31.   
  32.         /* 构建响应字符,为接收到客户端字节的数量 */  
  33.         memset(buffer, '0', 1024);  
  34.         sprintf(buffer, "Client: Server had received %.2d bytes from me!\n", size - 1);  
  35.         write(s, buffer, strlen(buffer) + 1);   /* 发给客户端 */  
  36.     }  
  37. }  
  38.   
  39. /************************************************* 
  40. * Function    :  
  41. * Description : 客户端的处理过程 
  42. * Calls       :  
  43. * Called By   :  
  44. * Input       :  
  45. * Output      :  
  46. * Return      :  
  47. *************************************************/  
  48. void process_conn_client(int s)  
  49. {  
  50.     ssize_t size = 0;  
  51.     char buffer[1024];          /* 数据的缓冲区 */  
  52.   
  53.     for (;;)  
  54.     {                           /* 循环处理过程 */  
  55.         /* 从标准输入中读取数据放到缓冲区buffer中 */  
  56.         size = read(0, buffer, 1024);  
  57.         if (size > 0)  
  58.         {                       /* 读到数据 */  
  59.             write(s, buffer, size); /* 发送给服务器 */  
  60.             size = read(s, buffer, 1024);   /* 从服务器读取数据 */  
  61.             write(1, buffer, size); /* 写到标准输出 */  
  62.         }  
  63.     }  
  64. }  
  65.   
  66. /************************************************* 
  67. * Function    :  
  68. * Description :  
  69. * Calls       :  
  70. * Called By   : tcp_server.c tcp_client.c 
  71. * Input       :  
  72. * Output      :  
  73. * Return      :  
  74. *************************************************/  
  75. void sig_proccess(int signo)  
  76. {  
  77.     printf("Catch a exit signal\n");  
  78.     exit(0);  
  79. }  
  80.   
  81. /************************************************* 
  82. * Function    :  
  83. * Description :  
  84. * Calls       :  
  85. * Called By   : tcp_server.c tcp_client.c 
  86. * Input       :  
  87. * Output      :  
  88. * Return      :  
  89. *************************************************/  
  90. void sig_pipe(int sign)  
  91. {  
  92.     printf("Catch a SIGPIPE signal\n");  
  93. }  

makefile文件:

[cpp] view plaincopy
  1. CC = gcc  
  2. all:client server  
  3.       
  4. client:tcp_process.o tcp_client.o  
  5.     $(CC) -o client tcp_process.o tcp_client.o  
  6. server:tcp_process.o tcp_server.o  
  7.     $(CC) -o server tcp_process.o tcp_server.o  
  8. clean:  
  9.     rm -f client server *.o  

测试结果:

[root@ShiGuang songjingbing]# ./server 8080
Server: Client had sent 11 bytes to me!
Server: Client had sent 11 bytes to me!
Server: Client had sent 41 bytes to me!


[root@ShiGuang songjingbing]# ./client 192.168.1.123 8080
fsafdsafsaf
Client: Server had received 11 bytes from me!
dfasfdsafsa
Client: Server had received 11 bytes from me!
ddddddddddddddddddddddddddddddddddddddddd
Client: Server had received 41 bytes from me!

0 0
原创粉丝点击