思想:
主进程专门用于连接多个客户端的请求,若有一条客户端连接进来,主进程就创建一个子进程,用该子进程来处理客户端的业务数据。
tcp_server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>//sockaddr_in
#include <unistd.h>
#include <arpa/inet.h> // 包含 inet_addr 函数的声明
#include <pthread.h>
#define BUF_SIZE 20void *ThreadFunc(void *arg)
{int iClient = *(int *)arg;char buf[BUF_SIZE] = {0};int ret = -1;while(1){ret = recv(iClient, buf, BUF_SIZE, 0);if(ret <= 0){printf("recv error!\r\n");close(iClient);pthread_exit("thread exit");}printf("server recv data:%s\r\n",buf);//sendsend(iClient, buf, BUF_SIZE, 0);}
}int main(int argc, const char *argv[])
{//1.socketint iServer = socket(AF_INET, SOCK_STREAM, 0);if(-1 == iServer){puts("----------1、create socket error!----------");return -1;}puts("----------1、create socket ok!----------");//2.bindstruct sockaddr_in stServer;stServer.sin_family = AF_INET;//第一个成员stServer.sin_port = htons(8888);//第二个成员stServer.sin_addr.s_addr = inet_addr("127.0.0.1");//将点分十进制ip地址转换为32位无符号整数int ret = bind(iServer, (struct sockaddr *)&stServer, sizeof(struct sockaddr));if(-1 == ret){puts("----------2、bind error!----------");return -1;}puts("----------2、bind ok!----------");//3.listenret = listen(iServer, 5);if(-1 == ret){puts("----------3、listen error!----------");return -1;}puts("----------3、listen ok!----------");//4.accept//函数原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);//函数作用:接收客户端的连接请求//参数1:文件描述符 ---> socket的返回值//参数2:指向存放对方主机信息结构体的指针//参数3:指向struct sockaddr大小的指针//返回值:成功返回 新的文件描述符 ---> 标识一个新的网络软通道 --->//用做收发正文数据(recv/send), 失败 -1struct sockaddr_in stClient;//存放对方的主机信息socklen_t len = sizeof(struct sockaddr_in);char buf[BUF_SIZE] = {0};while(1){memset(buf, 0, BUF_SIZE);int iClient = accept(iServer, (struct sockaddr *)&stClient, &len);if(-1 == iClient){continue;//当前客户端出错转向下一个客户端 }printf("----------4、accept ok! iClient = %d\r\n----------",iClient );//标准输入输出出错,所以下一个打开的文件一定是4// \r\n适用于所有操作系统,此考虑系统移植//threadpthread_t tID = -1;if(0 != pthread_create(&tID, NULL, ThreadFunc, &iClient)){perror("create thread error");close(iClient);continue;}printf("create thread ok! iClient:%d\r\n",iClient);}return 0;
}
tcp_client.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>#define BUF_SIZE 20
//main函数参数,如果需要键入IP则给定即可
int main(int argc, const char *argv[])
{//1、socketint iClient = socket(AF_INET, SOCK_STREAM, 0);if(-1 == iClient){puts("----------1、create socket error!");return -1;}puts("----------1、create socket ok!");//2、connectstruct sockaddr_in stServer;stServer.sin_family = AF_INET;stServer.sin_port = htons(8888);//stServer.sin_addr.s_addr = inet_addr("192.168.15.71");stServer.sin_addr.s_addr = inet_addr("127.0.0.1");int ret = connect(iClient, (struct sockaddr *)&stServer, sizeof(struct sockaddr_in));if(-1 == ret){puts("----------2、connect error!");return -1;}puts("----------2、connect ok!");char buf[BUF_SIZE] = {0};while(1){//gets();//char *fgets(char *s, int size, FILE *stream);fgets(buf, BUF_SIZE, stdin);//更安全,边界检查//3、send recvret = send(iClient, buf, BUF_SIZE, 0);if(-1 == ret){puts("----------3、send data error!");}printf("----------3、send data ok! buf = %s\r\n",buf);//recv//函数原型:ssize_t recv(int sockfd, void *buf, size_t len, int flags);memset(buf, 0, BUF_SIZE);ret = recv(iClient, buf, BUF_SIZE, 0);if(-1 == ret){puts("----------4、recv error!");return -1;}printf("----------4、recv data ok! buf = %s\r\n",buf);}//close(iClient);return 0;
}