Linux网络编程:TCP服务器(多进程)
Linux网络编程:TCP服务器(多进程)
服务器程序:tcp_server.c
- #include <stdio.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <unistd.h>
- #include <linux/in.h>
- #include <signal.h>
- extern void sig_proccess(int signo);
- #define BACKLOG 5 /* 侦听队列长度 */
- /*************************************************
- * Function :
- * Description : 服务端主程序
- * Calls : process_conn_server
- * Called By :
- * Input :
- * Output :
- * Return :
- *************************************************/
- int main(int argc, char *argv[])
- {
- if (argc != 2)
- {
- printf("Usage:%s port_number\n", argv[0]);
- return 1;
- }
- int port;
- int ss, sc; /* ss为服务器的socket描述符,sc为客户端的socket描述符 */
- struct sockaddr_in server_addr; /* 服务器地址结构 */
- struct sockaddr_in client_addr; /* 客户端地址结构 */
- int err; /* 返回值 */
- pid_t pid; /* 分叉的进行id */
- signal(SIGINT, sig_proccess);
- signal(SIGPIPE, sig_proccess);
- /* 建立一个流式套接字 */
- ss = socket(AF_INET, SOCK_STREAM, 0);
- if (ss < 0)
- { /* 出错 */
- printf("socket error\n");
- return -1;
- }
- //获得输入的端口
- port = atoi(argv[1]);
- /* 设置服务器地址 */
- bzero(&server_addr, sizeof(server_addr)); /* 清0 */
- server_addr.sin_family = AF_INET; /* 协议族 */
- server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 本地地址 */
- server_addr.sin_port = htons(port); /* 服务器端口 */
- /* 绑定地址结构到套接字描述符 */
- err = bind(ss, (struct sockaddr *)&server_addr, sizeof(server_addr));
- if (err < 0)
- { /* 出错 */
- printf("bind error\n");
- return -1;
- }
- /* 设置侦听 */
- err = listen(ss, BACKLOG);
- if (err < 0)
- { /* 出错 */
- printf("listen error\n");
- return -1;
- }
- /* 主循环过程 */
- for (;;)
- {
- int addrlen = sizeof(struct sockaddr);
- /* 接收客户端连接 */
- sc = accept(ss, (struct sockaddr *)&client_addr, &addrlen);
- if (sc < 0)
- { /* 出错 */
- continue; /* 结束本次循环 */
- }
- /* 建立一个新的进程处理到来的连接 */
- pid = fork(); /* 分叉进程 */
- if (pid == 0)
- { /* 子进程中 */
- close(ss); /* 在子进程中关闭服务器的侦听 */
- process_conn_server(sc); /* 处理连接 */
- }
- else
- {
- close(sc); /* 在父进程中关闭客户端的连接 */
- }
- }
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <strings.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <unistd.h>
- #include <linux/in.h>
- #include <signal.h>
- extern void sig_proccess(int signo);
- extern void sig_pipe(int signo);
- static int s;
- void sig_proccess_client(int signo)
- {
- printf("Catch a exit signal\n");
- close(s);
- exit(0);
- }
- /*************************************************
- * Function :
- * Description : 客户端主程序
- * Calls : process_conn_client
- * Called By :
- * Input :
- * Output :
- * Return :
- *************************************************/
- int main(int argc, char *argv[])
- {
- int port;
- struct sockaddr_in server_addr; /* 服务器地址结构 */
- int err; /* 返回值 */
- signal(SIGINT, sig_proccess);
- signal(SIGPIPE, sig_pipe);
- /* 建立一个流式套接字 */
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0)
- { /* 出错 */
- printf("socket error\n");
- return -1;
- }
- /* 将用户输入的字符串类型的IP地址转为整型 */
- inet_pton(AF_INET, argv[1], &server_addr.sin_addr);
- port = atoi(argv[2]);
- /* 设置服务器地址 */
- bzero(&server_addr, sizeof(server_addr)); /* 清0 */
- server_addr.sin_family = AF_INET; /* 协议族 */
- server_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 本地地址 */
- server_addr.sin_port = htons(port); /* 服务器端口 */
- /* 连接服务器 */
- connect(s, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
- process_conn_client(s); /* 客户端处理过程 */
- close(s); /* 关闭连接 */
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <signal.h>
- /*************************************************
- * Function :
- * Description : 服务器对客户端的处理
- * Calls :
- * Called By :
- * Input :
- * Output :
- * Return :
- *************************************************/
- void process_conn_server(int s)
- {
- ssize_t size = 0;
- char buffer[1024]; /* 数据的缓冲区 */
- for (;;)
- { /* 循环处理过程 */
- /* 从套接字中读取数据放到缓冲区buffer中 */
- memset(buffer, '0', 1024);
- size = read(s, buffer, 1024);
- if (size == 0)
- { /* 没有数据 */
- return;
- }
- printf("Server: Client had sent %.2d bytes to me!\n", size - 1);
- /* 构建响应字符,为接收到客户端字节的数量 */
- memset(buffer, '0', 1024);
- sprintf(buffer, "Client: Server had received %.2d bytes from me!\n", size - 1);
- write(s, buffer, strlen(buffer) + 1); /* 发给客户端 */
- }
- }
- /*************************************************
- * Function :
- * Description : 客户端的处理过程
- * Calls :
- * Called By :
- * Input :
- * Output :
- * Return :
- *************************************************/
- void process_conn_client(int s)
- {
- ssize_t size = 0;
- char buffer[1024]; /* 数据的缓冲区 */
- for (;;)
- { /* 循环处理过程 */
- /* 从标准输入中读取数据放到缓冲区buffer中 */
- size = read(0, buffer, 1024);
- if (size > 0)
- { /* 读到数据 */
- write(s, buffer, size); /* 发送给服务器 */
- size = read(s, buffer, 1024); /* 从服务器读取数据 */
- write(1, buffer, size); /* 写到标准输出 */
- }
- }
- }
- /*************************************************
- * Function :
- * Description :
- * Calls :
- * Called By : tcp_server.c tcp_client.c
- * Input :
- * Output :
- * Return :
- *************************************************/
- void sig_proccess(int signo)
- {
- printf("Catch a exit signal\n");
- exit(0);
- }
- /*************************************************
- * Function :
- * Description :
- * Calls :
- * Called By : tcp_server.c tcp_client.c
- * Input :
- * Output :
- * Return :
- *************************************************/
- void sig_pipe(int sign)
- {
- printf("Catch a SIGPIPE signal\n");
- }
- CC = gcc
- all:client server
- client:tcp_process.o tcp_client.o
- $(CC) -o client tcp_process.o tcp_client.o
- server:tcp_process.o tcp_server.o
- $(CC) -o server tcp_process.o tcp_server.o
- clean:
- rm -f client server *.o
[root@ www.bkjia.com ]# ./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@ www.bkjia.com ]# ./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!
评论暂时关闭