这里很简单的使用了fork()函数,在执行了fork()以后的所有代码都会由子进程和父进程同时执行。
他们同时拥有相同的资源(两份拷贝),所以在子进程执行的过程中,子进程需要先close掉listenfd(监听套接字),以免过多占用系统资源。
而父进程继续监听listenfd,如果有新的连接出现,则会再次添加一个子进程。
这个tcp服务端的功能也是十分简单,就是将客户端的消息,原封不动地发回去。
代码如下
#include "socket_includes.h"int create_socket();
int process_data(int sockfd);int main(int argc,char **argv)
{ struct sockaddr_in cliaddr;int sockfd, listenfd;int cli_addr_len;printf("My pid is %d\n",getpid());listenfd = create_socket();if(listenfd < 0){printf("create_socket err\n");return -1;}for(;;){cli_addr_len = sizeof(cliaddr);sockfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cli_addr_len);if(sockfd < 0){printf("accept err:\n");continue;}if(fork() == 0){//就是这里!新建了一个子进程。close(listenfd);//子进程关闭不要用的套接字。父进程没有关闭,他们是两套拷贝printf("My pid is %d\n",getpid()); //打印PIDprocess_data(sockfd); //数据处理的过程我用函数打包了一下exit(0);}close(sockfd); //子进程和父进程都会关闭sockfd}close(listenfd);return 0;
} int process_data(int sockfd){int bytes, err;char buff[MAX_BUFF_LINE];printf("产生了一个新的客户连接\n");for(;;){bytes = recv(sockfd,buff, MAX_BUFF_LINE, 0);if(bytes < 0){printf("recv err:\n");continue;}buff[bytes] = '\0';if(!strcmp(buff, "q")){printf("客户连接退出了!\n");err = send(sockfd, "quit!\n", strlen("quit!\n"), 0);close(sockfd);exit(0); }printf("%s", buff); err = send(sockfd, buff, bytes, 0);if(err < 0){printf("send err:\n");continue;}}
}int create_socket(){int listenfd, err;int ser_addr_len;struct sockaddr_in servaddr;listenfd = socket(AF_INET, SOCK_STREAM, 0);if(listenfd < 0){printf("socket err:");return -1; }//清零IP地址结构体bzero(&servaddr, sizeof(servaddr));//填写必要的信息servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(PORT);ser_addr_len = sizeof(servaddr);err = bind(listenfd, (struct sockaddr *)&servaddr, ser_addr_len);if(err < 0){printf("bind err:");return -1;}err = listen(listenfd, 10);if(err < 0){printf("listen err:");return -1; }printf("listen the port:%d\n", PORT); return listenfd;
}
头文件"socket_includes.h"的内容是:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
#include <errno.h> #define MAX_BUFF_LINE 100
#define PORT 9999