客户端通过服务端进行通信
输入reg,进行注册
输入send,输入name,向其他客户端发送信息
输入all,向其他所有客户端发送信息
客户端的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<pthread.h>
#define PORT 33333
#define LINE 1024
struct message
{
int action;
char toname[20];
char msg[1024];
};
void * recv_message(void *arg)
{
int ret;
int cfd = *((int *)arg);
struct message *msg = (struct message *)malloc(sizeof(struct message));
while(1)
{
memset(msg,0,sizeof(struct message));
ret = recv(cfd,msg,sizeof(struct message),0);
if(ret < 0)
{
perror("recv error!\n");
exit(1);
}
if(ret == 0)
{
printf("%d is closed\n",cfd);
pthread_exit(NULL);
}
switch(msg->action)
{
case 1:
{
printf("reg success!\n");
break;
}
case 2:
{
printf("recv success!\n");
printf("recv message:%s\n",msg->msg);
break;
}
case 3:
{
printf("all recv success!\n");
printf("all recv message:%s\n",msg->msg);
break;
}
}
usleep(3);
}
pthread_exit(NULL);
}
int main()
{
int sockfd;
char buffer[1024];
pthread_t id;
char cmd[20];
char name[20];
char toname[20];
char message[1024];
struct sockaddr_in s_addr;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket error!");
exit(1);
}
printf("client socket success!\n");
bzero(&s_addr,sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(sockfd,(struct sockaddr *)(&s_addr),sizeof(struct sockaddr_in)) < 0)
{
perror("connect error!\n");
exit(1);
}
printf("connect success!\n");
if(pthread_create(&id,NULL,recv_message,(void *)(&sockfd))!=0)
{
perror("error\n");
exit(1);
}
struct message *msg = (struct message *)malloc(sizeof(struct message));
printf("cmd : reg send all!\n...");
while(1)
{
printf("Please input cmd:\n");
scanf("%s",cmd);
if(strcmp(cmd,"reg") == 0)
{
printf("Please input reg name:\n");
scanf("%s",name);
msg->action = 1;
strcpy(msg->msg,name);
if(send(sockfd,msg,sizeof(struct message),0) < 0)
{
printf("send name error\n");
exit(1);
}
}
if(strcmp(cmd,"send") == 0)
{
printf("Please input send to name:\n");
scanf("%s",toname);
printf("Please send message :\n");
scanf("%s",message);
msg->action = 2;
strcpy(msg->toname,toname);
strcpy(msg->msg ,message);
if(send(sockfd,msg,sizeof(struct message),0) < 0)
{
printf("send message error\n");
exit(1);
}
}
if(strcmp(cmd,"all") == 0)
{
printf("Please input all message:\n");
scanf("%s",message);
msg->action = 3;
strcpy(msg->msg ,message);
send(sockfd,msg,sizeof(struct message),0);
}
}
shutdown(sockfd,SHUT_RDWR);
return 0;
}
服务器的代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<pthread.h>
#define PORT 33333
struct message
{
int action;
char toname[20];
char msg[1024];
};
struct online
{
int cfd;
char name[20];
struct online *next;
};
struct online *head = NULL;
void insert_user(struct online *new)
{
if(head == NULL)
{
new->next = NULL;
head = new;
}
else
{
new->next = head->next;
head->next = new;
}
}
int find_cfd(char *toname)
{
if(head == NULL)
{
return -1;
}
struct online *temp = head;
while(temp != NULL)
{
if(strcmp(temp->name ,toname) == 0)
{
return temp->cfd ;
}
temp= temp->next ;
}
return -1;
}
void * recv_message(void *arg)
{
int ret;
int to_cfd;
int cfd =*((int *)arg);
struct message *msg = (struct message *)malloc(sizeof(struct message));
struct online *new;
while(1)
{
memset(msg,0,sizeof(struct message));
ret = recv(cfd,msg,sizeof(struct message),0);
if(ret < 0)
{
printf("recv error!\n");
exit(1);
}
if(ret == 0)
{
printf("%d is closed\n",cfd);
pthread_exit(NULL);
}
switch(msg->action)
{
case 1:
{
printf("client reg success!\n");
new = (struct online *)malloc(sizeof(struct online));
new->cfd = cfd;
strcpy(new->name ,msg->msg);
insert_user(new);
msg->action = 1;
send(cfd,msg,sizeof(struct message),0);
break;
}
case 2:
{
to_cfd = find_cfd(msg->toname );
msg->action = 2;
send(to_cfd,msg,sizeof(struct message),0);
break;
}
case 3:
{
struct online *temp = head;
while(temp != NULL)
{
to_cfd = temp->cfd ;
msg->action = 3;
send(to_cfd,msg,sizeof(struct message),0);
temp = temp->next ;
}
break;
}
}
usleep(3);
}
pthread_exit(NULL);
}
int main()
{
int cfd;
int sockfd;
int len;
char buf[1024];
struct sockaddr_in addr;
struct sockaddr_in c_addr;
pthread_t id;
sockfd=(socket(AF_INET,SOCK_STREAM,0));
if(sockfd==-1)
{
perror("socket error\n");
exit(1);
}
printf("socket success\n");
int opt=1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_port=htons(PORT);//瀛楄妭搴忚浆鍖?杞垚鏈湴鐨勭鍙e彿
//addr.sin_addr.s_addr=inet_addr(ip_addr);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(bind(sockfd,(struct sockaddr*)(&addr),sizeof(struct sockaddr_in))<0)
{
perror("bind error\n");
exit(1);
}
printf("bind success\n");
if(listen(sockfd,3)<0)
{
perror("listen error\n");
exit(1);
}
printf("listen success\n");
while(1)
{
memset(buf,0,sizeof(buf));
bzero(&c_addr,sizeof(struct sockaddr_in));
len=sizeof(struct sockaddr_in);
printf("accepting.........\n");
if((cfd=accept(sockfd,(struct sockaddr*)(&c_addr),&len))==-1)
{
perror("accept error\n");
exit(1);
}
printf("port=%d ip=%s\n",ntohs(c_addr.sin_port),inet_ntoa(c_addr.sin_addr));
if(pthread_create(&id,NULL,recv_message,(void *)(&cfd)) != 0)
{
printf("pthread create error\n");
exit(1);
}
sleep(2);
}
return 0;
}
运行结果如下: