一.进程实现TCP并发服务器
#include <func.h>
#define PORT 6666
#define IP "192.168.124.42"void handler(int arm)
{while(waitpid(-1,NULL,WNOHANG) > 0);
}
int main(int argc, const char *argv[])
{//接受17号信号signal(17, handler);int sfd = socket(AF_INET,SOCK_STREAM,0); //创建流式套接字printf("sfd create success\n");//绑定 ip 和端口//填充结构体信息struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT);sin.sin_addr.s_addr = inet_addr(IP);bind(sfd, (struct sockaddr*)&sin, sizeof(sin)); //设置为监听模式listen(sfd,128);//接受客户端信息结构体struct sockaddr_in cin;socklen_t len = sizeof(cin);while(1){//创建新的套接字//父进程进行接受信息int newfd = accept(sfd, (struct sockaddr*)&cin, &len);printf("newfd= %d 客户端连接成功 __%d__\n", newfd, __LINE__);int cpid = fork(); //创建父子进程if(0 == cpid ) //子进程进行信息传递{close(sfd);char arr[128] = "";int a = 0;while(1){//收bzero(arr, sizeof(arr));a = recv(newfd, arr, sizeof(arr), 0);if(a < 0){ERR_MSG("recv");return -1;}if(a == 0){printf("newfd= %d 客户端退出\n", newfd);}printf("接受成功 客户端信息arr= %s\n", arr);//发strcpy(arr, "~_~");send(newfd, arr,sizeof(arr),0);printf("%s 发送成功\n", arr);}exit(0);}}close(sfd);return 0;
}
现象
二、线程
#include <func.h>
#include <pthread.h>
#define PORT 6666
#define IP "192.168.124.42"struct demo
{int newfd;struct sockaddr_in cin; //接收客户端的地址信息
};int chlid(int newfd,struct sockaddr_in cin);void* callbake(void * arg)
{int newfd = ((struct demo*)arg)->newfd; //传参数struct sockaddr_in cin = ((struct demo*)arg)->cin; chlid(newfd,cin);//传到函数内部相当另存一个 newfdclose(newfd);pthread_exit(NULL);
}int main(int argc, const char *argv[])
{//创建流式套接 int sfd = socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){ERR_MSG("sfd");return -1;}printf("socket create succes sfd=%d __%d__\n", sfd, __LINE__);//定义并填充地址信息结构体,给服务器绑定//真实的地址信息结构体根据地址族指定 AF_INET :man ip(7)struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(PORT); //端口号的网络字节序 : 1024-49151sin.sin_addr.s_addr = inet_addr(IP); //本机号的网络字节序列//绑定服务器自身的地址信息----必须绑定if(bind(sfd,(struct sockaddr*) &sin, sizeof(sin)) <0){ERR_MSG("bind");return -1;}//将套接字设置为被动监听状态if(listen(sfd, 128) <0){ERR_MSG("listen");return -1;}printf("listen succress __%d__\n", __LINE__);struct demo info; //定义结构体socklen_t addrlen = sizeof(info.cin);//获取连接成功的客户端信息,生成一个新的套接字while(1){info.newfd = accept(sfd,(struct sockaddr *)&info.cin, &addrlen);if(info.newfd < 0){ERR_MSG("accept");return -1;}printf("newfd= %d 客户端连接成功 __%d__\n",info.newfd,__LINE__);pthread_t tid;pthread_create(&tid, NULL,callbake,(void*)&infoi); // 创建一个线程pthread_detach(tid);}//关闭文件描述符if(close(sfd) < 0){ERR_MSG("close");return -1;}return 0;
}int chlid(int newfd,struct sockaddr_in cin)
{ssize_t a = 0;ssize_t b = 0;char arr[128] = "";char crr[128] = "";while(1){//接收客户端数据bzero(arr, sizeof(arr));a = recv(newfd, arr, sizeof(arr), 0);if(a < 0 ){ERR_MSG("recv");return -1;}if(a == 0){printf("对端关闭发送结束\n");printf("[%s:%d]\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));//客户端的端口 ipbreak;}printf("[%s:%d]\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));//客户端的端口 ipprintf("对端成功接收\n");printf("客户端信息:%s\n", arr);//向客户端发送数据printf("请输入需要发送的数据-->");fgets(crr,sizeof(crr), stdin);b = send(newfd, crr, sizeof(crr), 0);printf("发送成功");}
}
现象