多线程与多进程的做法区别不大,思路一样,都是执行两个死循环,一个循环等待客户端连接,一个循环与客户端通信。多进程的方式请点此处
服务器
#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作为文件描述符默认为阻塞,当客户端关闭时立即返回0
if(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;
}