客户端
#include <myhead.h>
#define SER_IP "192.168.125.244"
#define SER_PORT 8888
typedef struct Node
{
char username[20];
struct sockaddr_in cin;
struct Node *next;
}Node,*Node_p;
typedef struct
{
int flag;
char username[20];
char data[1024];
}msg,*msg_p;
Node_p HEAD;
int SFD;
//新建客户端地址结点
Node_p create_node(Node_p head,char *username,struct sockaddr_in *cin)
{
Node_p p=(Node_p)malloc(sizeof(Node));
strcpy(p->username,username);
p->cin=*cin;
p->next=head;
return p;
}
//插入客户端地址结点
void insert_node(Node_p head,Node_p new)
{
new->next=head->next;
head->next=new;
}
//删除客户端地址结点
void delete_node(Node_p head,char *username)
{
Node_p temp=head;
while(strcmp(temp->next->username,username))
{
temp=temp->next;
}
Node_p delete=temp->next;
temp->next=delete->next;
free(delete);
delete=NULL;
}
//伪广播
void sendtoall(int sfd,Node_p head,msg_p buf,socklen_t socklen)
{
Node_p temp=head;
while(temp->next!=NULL)
{
if(sendto(sfd,buf,sizeof(msg),0,(struct sockaddr*)&temp->cin,socklen)==-1)
{
perror("sendto err");
return ;
}
temp=temp->next;
}
}
//服务端发送信息子线程函数
void *comm(void *arg)
{
while(1)
{
msg_p commbuf=(msg_p)malloc(sizeof(msg));
commbuf->flag=1;
strcpy(commbuf->username,"主机");
scanf("%s",commbuf->data);
while(getchar()!=10);
sendtoall(SFD,HEAD,commbuf,sizeof(commbuf));
}
return 0;
}
int main(int argc, const char *argv[])
{
//创建套接字
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("socket err");
return -1;
}
//绑定主机地址
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind err");
return -1;
}
int reuse=1;
//设置端口重用
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt err");
return -1;
}
//创建客户端地址容器
struct sockaddr_in cin;
socklen_t socklen=sizeof(cin);
//创建保存客户端地址的链表头结点
Node_p head=(Node_p)malloc(sizeof(Node));
char *host="host";
strcpy(head->username,host);
head->cin=sin;
head->next=NULL;
//创建发送信息子线程
HEAD=head;
SFD=sfd;
pthread_t td;
if(pthread_create(&td,NULL,comm,NULL))
{
perror("pthread_create");
return -1;
}
pthread_detach(td);
//创建消息包容器
msg_p buf=(msg_p)malloc(sizeof(msg));
while(1)
{
bzero(buf,sizeof(buf));
recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&socklen);
switch(buf->flag)
{
case 0://登录
Node_p new=create_node(head,buf->username,&cin);
insert_node(head,new);
sendtoall(sfd,head,buf,socklen);
break;
case 1://聊天
sendtoall(sfd,head,buf,socklen);
break;
case 2://下线
delete_node(head,buf->username);
sendtoall(sfd,head,buf,socklen);
break;
default:
break;
}
}
free(buf);
buf=NULL;
return 0;
}