TCP使用多线程实现多用户通信
#include<myhead.h>
#define SERPORT 8888
#define SERIP "192.168.0.143"
#define BACKLOG 10
typedef struct {
int newfd;//储存新的文件描述符
struct sockaddr_in cin;//储存客户端信息
}SIG;
void *accept_newcli(void *sig){
SIG client = *(SIG *)sig;
int newfd = client.newfd;
struct sockaddr_in cin = client.cin;
char buff[1024];
while(1){
memset(buff,0,sizeof(buff));
int len = recv(newfd,buff,sizeof(buff),0);
printf("收到%s:%d的消息:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buff);
if(len==0){
printf("客户端退出\n");
break;
}
}
//关闭文件描述符
close(newfd);
pthread_exit(NULL);
}
int main (int argc, const char *argv[])
{
//创建套接字
int oldfd = socket(AF_INET,SOCK_STREAM,0);
if(oldfd==-1){
perror("oldfd");
return -1;
}
printf("socket创建成功\n");
//端口复用
int k = 1;
if(setsockopt(oldfd,SOL_SOCKET,SO_REUSEADDR,&k,sizeof(k))==-1){
perror("setsockopt");
return -1;
}
printf("端口复用成功\n");
//绑定
struct sockaddr_in sin={
.sin_family = AF_INET,
.sin_port = htons(SERPORT),
.sin_addr.s_addr = inet_addr(SERIP)
};
if(bind(oldfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
perror("bind");
return -1;
}
printf("绑定成功\n");
//监听
if(listen(oldfd,BACKLOG)==-1){
perror("listen");
return -1;
}
printf("监听成功\n");
struct sockaddr_in cin;
int cin_len = sizeof(cin);
//接收消息
SIG MSG;
while(1){
int newfd = accept(oldfd,(struct sockaddr *)&cin,&cin_len);
if(newfd==-1){
perror("newfd");
return -1;
}
printf("%s:%d发来请求\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
MSG.newfd = newfd;
MSG.cin = cin;
//创建子线程与客户交流
pthread_t tid;
if(pthread_create(&tid,NULL,accept_newcli,&MSG)!=0){
perror("pthread_create");
return -1;
}
pthread_detach(tid);
}
close(oldfd);
return 0;
}
TCP使用多进程实现多用户通信
#include<myhead.h>
#define SERIP "192.168.0.143"
#define SERPORT 8888
#define BACKLOG 20
int main (int argc, const char *argv[])
{
int oldfd = socket(AF_INET,SOCK_STREAM,0);
if(oldfd==-1){
perror("oldfd");
return -1;
}
int k=1;
if(setsockopt(oldfd,SOL_SOCKET,SO_REUSEPORT,&k,sizeof(k))==-1){
perror("setsockopt");
return -1;
}
struct sockaddr_in sin={
.sin_family = AF_INET,
.sin_port = htons(SERPORT),
.sin_addr.s_addr = inet_addr(SERIP)
};
if(bind(oldfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
perror("bind");
return -1;
}
if(listen(oldfd,BACKLOG)==-1){
perror("listen");
return -1;
}
//创建子线程
struct sockaddr_in cin;
int cin_len = sizeof(cin);
while(1){
int newfd = accept(oldfd,(struct sockaddr *)&cin,&cin_len);
if(newfd==-1){
perror("newfd");
return -1;
}
printf("%s:%d连接成功\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
pid_t pid = fork();
if(pid>0){//父进程
close(newfd);
}else if(pid==0){
close(oldfd);
char buff[1024];
while(1){
memset(buff,0,sizeof(buff));
int len = recv(newfd,buff,sizeof(buff),0);
if(len==0){
printf("客户端退出\n");
break;
}
printf("服务器端收到消息\n");
printf("来自%s:%d的消息:%s\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),buff);
strcat(buff,"^-^");
send(newfd,buff,strlen(buff),0);
}
close(newfd);
exit(0);
}else{
perror("fork");
return -1;
}
}
close(oldfd);
return 0;
}