多线程与多进程的做法区别不大,思路一样,都是执行两个死循环,一个循环等待客户端连接,一个循环与客户端通信。多进程的方式请点此处
服务器
#include <sys/socket.h>
#include <pthread.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/types.h>typedef struct client_new
{char *ip_addr;int sockid;
}client_new;//存放当前客户端信息void *do_work(void *client_)
{client_new client=*((client_new *)client_);//强转char receive[100]={0};while(1){memset(receive,0,sizeof(receive));int ret=read(client.sockid,receive,sizeof(receive));//socket作为文件描述符默认为阻塞,当客户端关闭时立即返回0if(ret==0){printf("%s 客户端已关闭\n",client.ip_addr);pthread_exit(NULL);}printf("%s :",client.ip_addr);fputs(receive,stdout);write(client.sockid,receive,ret);}
}
int main()
{int client_sockid=0;struct sockaddr_in sock;memset(&sock,0,sizeof(sock));sock.sin_family=AF_INET;sock.sin_port=htons(5188);sock.sin_addr.s_addr=htonl(INADDR_ANY);int sockid=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);const int on=1;if(setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)//设置端口重复利用{printf("setsockopt\n");return 0;}if(bind(sockid,(struct sockaddr *)&sock,sizeof(sock))<0){printf("bind\n");return 0;}if(listen(sockid,SOMAXCONN)<0){printf("listen\n");return 0;}struct sockaddr_in client_sockaddr;socklen_t other_socklen=sizeof(client_sockaddr);pthread_t tid=0;while(1){client_sockid=accept(sockid,(struct sockaddr *)&client_sockaddr,&other_socklen);//如果没有客户端连接,accept就阻塞在这里if(client_sockid<0){continue;}client_new client;client.ip_addr=inet_ntoa(client_sockaddr.sin_addr);client.sockid=client_sockid;printf("ip=%s port=%d 已连接\n",inet_ntoa(client_sockaddr.sin_addr),ntohs(client_sockaddr.sin_port));pthread_create(&tid,NULL,do_work,(void *)&client);//创建线程,只要有客户端连接就创建一个线程去和客户端通信}close(sockid);return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>int main()
{struct sockaddr_in sock;memset(&sock,0,sizeof(sock));sock.sin_family=AF_INET;sock.sin_port=htons(5188);sock.sin_addr.s_addr=inet_addr("127.0.0.1");int sockid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);socklen_t socklen=sizeof(sock);if(connect(sockid,(struct sockaddr *)&sock,socklen)<0){printf("connect\n");return 0;}char send[100]={0};char receive[100]={0};while(1) {fgets(send,sizeof(send),stdin);if(strcmp(send,"NULL\n")==0)//输入NULL退出客户端{break;}write(sockid,send,strlen(send));read(sockid,receive,sizeof(receive));fputs(receive,stdout);memset(receive,0,strlen(receive));memset(send,0,strlen(send));}close(sockid);return 0;
}