多进程处理tcp服务器端demo
头文件
#ifndef __TCP_PROCESS_TEST_H__
#define __TCP_PROCESS_TEST_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#define SERV_PORT 5001
#define SERV_IP_ADDR "192.168.253.130"
#define BACKLOG 5
#define QUIT_STR "quit"
#endif
主程序
1,创建socket fd
2,绑定
3,listen
4,accept
5,创建多进程
6,在子进程中处理
#include <signal.h>
#include "net.h"
void cli_data_handle(void *arg);
void sig_child_handle(int signo){
if(SIGCHLD == signo){
waitpid(-1, NULL, WNOHANG);
}
}
int main(){
int fd = -1;
struct sockaddr_in sin;
1,创建socket fd
/***************************/
/**1, 创建socket fd*********/
/***************************/
if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
perror("socket");
exit(1);
}
//优化:允许绑定地址快速复用
int b_reuse = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int));
2,绑定
/***************************/
/**2, 绑定******************/
/***************************/
//2.1 填充struct sockaddr_in结构体
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(SERV_PORT);
//优化:服务器绑定任意IP
sin.sin_addr.s_addr = htonl(INADDR_ANY);
//2.2 绑定
if(bind(fd,(struct sockaddr *) &sin, sizeof(sin)) < 0){
perror("bind");
exit(1);
}
3,listen
/*******************************/
/**3, 调用listen()转换被动套接字/
/*******************************/
if(listen(fd, BACKLOG) < 0){
perror("listen");
exit(1);
}
printf("Server starting......OK!\n");
4,阻塞等待accept
当有客户端链接,创建子进程处理newfd,accept继续等待
/*******************************/
/**4, 阻塞等待客户端链接请求****/
/*******************************/
int newfd = -1;
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);
while(1){
pid_t pid = -1;
if((newfd = accept(fd, (struct sockaddr *) &cin, &addrlen)) < 0){
perror("accept");
exit(1);
}
//创建子进程处理已建立链接的客户端的交互数据
if((pid = fork()) < 0){
perror("fork");
break;
}
if(0 == pid){
close(fd);
char ipv4_addr[16];
if(!inet_ntop(AF_INET, (void *) &cin.sin_addr, ipv4_addr, sizeof(cin))){
perror("inet_ntop");
exit(1);
}
printf("Client(%s:%d) is connected!\n", ipv4_addr, ntohs(cin.sin_port));
cli_data_handle(&newfd);
return 0;
}else{
close(newfd);
}
}
close (fd);
return 0;
}
5,子进程处理程序
void cli_data_handle(void *arg){
int newfd = *(int *) arg;
printf("Child handling process: newfd =%d\n", newfd);
FILE *fp;
if((fp = fopen("net_test.txt", "a+")) == NULL){
perror("fopen");
exit(1);
}
//和newfd进行数据读写
int ret =-1;
char buf[BUFSIZ];
while(1){
bzero(buf, BUFSIZ);
do{
ret = read(newfd, buf, BUFSIZ -1);
}while(ret < 0 && EINTR == errno);
if(ret < 0){
perror("read");
exit (1);
}
if(!ret){
break;
}
printf("Receive data:%s\n", buf);
fputs(buf, fp);
if(!strncasecmp (buf, QUIT_STR, strlen(QUIT_STR))){
printf("Client(fd = %d) is exiting!\n", newfd);
break;
}
}
close(newfd);
}
多进程处理tcp客户端demo: link