服务器端
#include <myhead.h>
#define UDPIP "192.168.115.92"
#define UDPPORT 6666
//存储客户信息的链表结构体
typedef struct Node
{
char name[20];
struct sockaddr_in cin;
struct Node *next;
}*linklist;
//数据结构体
struct data_cli
{
char type;
char name[20];
char text[128];
};
//创建节点
linklist create_space()
{
linklist s=(linklist)malloc(sizeof(struct Node));
if(NULL==s)
return NULL;
bzero(s->name,sizeof(s->name));
s->next=NULL;
return s;
}
//末尾插入信息
linklist Insert_end(linklist head,struct sockaddr_in cin,char name[20])
{
//创建节点
linklist s=create_space();
s->cin=cin;
strcpy(s->name,name);
//判断之前是否有节点
if(NULL==head)
{
head=s;
return head;
}
linklist p=head;
while((p->next)!=NULL)
{
p=p->next;
}
p->next=s;
//未尾插入
return head;
}
//删除退出客户
linklist Delete_by_ele(linklist head,in_port_t cin_port)
{
if(NULL==head)
return NULL;
linklist p=head;
if(NULL==head->next)
{
free(head);
return NULL;
}
while(p!=NULL)
{
if(ntohs(cin_port)==ntohs(p->cin.sin_port))
{
linklist del=p->next;//多个字节
p->cin=del->cin;
strcpy(p->name,del->name);
p->next=del->next;
free(del);del=NULL;
return head;
}
if(p->next->next==NULL)
{
linklist q=p->next;
free(q);
p->next=NULL;
return head;
}
p=p->next;
}
return head;
}
int main(int argc, const char *argv[])
{
//创建头指针
linklist head=NULL;
//1.创建套接字文件
int tfd;
if((tfd=socket(AF_INET,SOCK_DGRAM,0))==-1)
{
perror("socket");
return -1;
}
//2.绑定IP和端口
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(UDPPORT);
sin.sin_addr.s_addr=inet_addr(UDPIP);
if(bind(tfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind");
return -1;
}
printf("bind successn");
//io多路复用信息
fd_set readfds,tempfds;
FD_ZERO(&readfds);
FD_SET(0,&readfds);
FD_SET(tfd,&readfds);
int maxfd=tfd;
//3.收发信息
struct sockaddr_in cin1;
cin1.sin_family=AF_INET;
socklen_t len=sizeof(cin1);
char buf[128]="";
int res;
struct data_cli cli_data;
while(1)
{
tempfds=readfds;
//等待唤醒条件
res=select(maxfd+1,&tempfds,NULL,NULL,NULL);
if(res<0)
{
perror("select");
return -1;
}
else if(res==0)
{
printf("超时n");
return -1;
}
if(FD_ISSET(0,&tempfds))
{
//系统向所有客户端发消息
bzero(&cli_data,sizeof(struct data_cli));
strcpy(cli_data.name,"系统消息:");
fgets(cli_data.text,sizeof(cli_data.text),stdin);
cli_data.text[strlen(cli_data.text)-1]=0;
linklist p=head;
while(p!=NULL)
{
sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);
p=p->next;
}
printf("系统发送消息成功n");
}
if(FD_ISSET(tfd,&tempfds))
{
bzero(&cli_data,sizeof(struct data_cli));
recvfrom(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&cin1,&len);
switch(cli_data.type)
{
case 'D':
{
strcpy(cli_data.text,"上线了");
linklist p=head;
while(p!=NULL)
{
sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);
p=p->next;
}
head=Insert_end(head,cin1,cli_data.name);
printf("[%s:%d]:%sn",inet_ntoa(cin1.sin_addr),ntohs(cin1.sin_port),"登录成功");
}
break;
case 'S':
{
linklist p=head;
while(p!=NULL)
{
if(p->cin.sin_port==cin1.sin_port)
{
if(p->next!=NULL)
{
p=p->next;
}else{break;}
}
sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);
p=p->next;
}
printf("[%s:%d]:%sn",inet_ntoa(cin1.sin_addr),ntohs(cin1.sin_port),"客户端发送消息");
}
break;
case 'Q':
{
head=Delete_by_ele(head,cin1.sin_port);
strcpy(cli_data.text,"下线了");
linklist p=head;
while(p!=NULL)
{
sendto(tfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&p->cin,len);
p=p->next;
}
printf("[%s:%d]:%sn",inet_ntoa(cin1.sin_addr),ntohs(cin1.sin_port),"客户端退出");
}
break;
}
}
}
//4.关闭文件
close(tfd);
return 0;
}
#include <myhead.h>
#define IP "192.168.115.92"
#define PORT 6666
//定义信息结构体
struct data_cli
{
char type;
char name[20];
char text[128];
};
int main(int argc, const char *argv[])
{
//1.创建套接字
int cfd;
cfd=socket(AF_INET,SOCK_DGRAM,0);
if(cfd==-1)
{
perror("socket");
return -1;
}
//io多路复用信息
fd_set readfds,tempfds;
FD_ZERO(&readfds);
FD_SET(0,&readfds);
FD_SET(cfd,&readfds);
int maxfd=cfd;
//3.收发数据
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(PORT);
sin.sin_addr.s_addr=inet_addr(IP);
socklen_t len=sizeof(struct sockaddr_in);
//创建账户
struct data_cli cli_data;
bzero(&cli_data,sizeof(struct data_cli));
printf("请登录用户:");
cli_data.type='D';
fgets(cli_data.name,sizeof(cli_data.name),stdin);
cli_data.name[strlen(cli_data.name)-1]=0;
char myname[20]="";
strcpy(myname,cli_data.name);
sendto(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,len);
char buf[256]="";
int res;
while(1)
{
tempfds=readfds;
//等待唤醒条件
res=select(maxfd+1,&tempfds,NULL,NULL,NULL);
if(res<0)
{
perror("select");
return -1;
}
else if(res==0)
{
printf("超时n");
return -1;
}
if(FD_ISSET(0,&tempfds))
{
bzero(&cli_data,sizeof(struct data_cli));
cli_data.type='S';
strcpy(cli_data.name,myname);
fgets(cli_data.text,sizeof(cli_data.text),stdin);
cli_data.text[strlen(cli_data.text)-1]='';
if(strcmp("quit",cli_data.text)==0)
{
cli_data.type='Q';
sendto(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,len);
break;
}
sendto(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,len);
}
if(FD_ISSET(cfd,&tempfds))
{
bzero(buf,sizeof(buf));
bzero(&cli_data,sizeof(struct data_cli));
recvfrom(cfd,&cli_data,sizeof(struct data_cli),0,(struct sockaddr*)&sin,&len);
sprintf(buf,"[%s]:%s",cli_data.name,cli_data.text);
printf("%sn",buf);
}
}
//4.关闭
close(cfd);
return 0;
}
原文地址:https://blog.csdn.net/qq_62936323/article/details/134616864
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_7237.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。