lts.h
#ifndef UDP
#define UDP
#include <myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.8.1"
typedef struct Node{
char username[20];
struct sockaddr_in cin;
struct Node *next;
}Node,*NodePtr;
typedef struct Message{
int type;//消息类型 1:login 2:logout 3:chat
char username[20];
char text[1024];
}Message;
#endif
客户端
#include "udpAssociate.h"
int cfd;
struct sockaddr_in in;
void * udp_send(void *arg){
Message message;
printf("请输入用户名:");
scanf("%s",message.username);
getchar();
while(1){
printf("请输入发送的消息类型:");
scanf("%d",&message.type);
getchar();
if(message.type==1||message.type==2){
sendto(cfd,&message,sizeof(message),0,(struct sockaddr*)&in,sizeof(in));
}else if(message.type==3){
printf("请输入要发送的消息:");
scanf("%s",message.text);
getchar();
sendto(cfd,&message,sizeof(message),0,(struct sockaddr*)&in,sizeof(in));
}
printf("发送成功\n");
if(message.type==2){
break;
}
}
pthread_exit(NULL);
}
void * udp_recvive(void *arg){
Message message;
while(1){
if(recv(cfd,&message,sizeof(message),0)<=0){
break;
}
if(message.type==3){
printf("%s:%s\n",message.username,message.text);
}else{
printf("收到服务器消息:%s%s\n",message.username,message.text);
}
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
// 创建套接字
cfd = socket(AF_INET, SOCK_DGRAM, 0);
if (cfd < 0) {
perror("socket error");
return -1;
}
// 服务器结构体
in.sin_family = AF_INET;
in.sin_port = htons(SER_PORT);
in.sin_addr.s_addr = inet_addr(SER_IP);
pthread_t pid1=-1,pid2=-1;
if(pthread_create(&pid1,NULL,udp_send,NULL)!=0){
perror("pthread_create error");
return -1;
}
if(pthread_create(&pid2,NULL,udp_recvive,NULL)!=0){
perror("pthread_create error");
return -1;
}
pthread_detach(pid1);
pthread_detach(pid2);
while(1);
return 0;
}
服务端
#include "udpAssociate.h"
int cfd;
NodePtr head;
//发送消息标志 1发 0不发
int flag=0;
Message message;
void * udp_send(void *arg){
while(1){
if(flag){
if(message.type==1){
strcpy(message.text,"已登录");
NodePtr p=head->next;
while(p){
sendto(cfd,&message,sizeof(message),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
p=p->next;
}
}else if(message.type==2){
strcpy(message.text,"已下线");
NodePtr p=head->next;
while(p){
sendto(cfd,&message,sizeof(message),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
p=p->next;
}
}else{
NodePtr p=head->next;
while(p){
sendto(cfd,&message,sizeof(message),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
p=p->next;
}
}
printf("发送成功\n");
flag=0;
}
}
pthread_exit(NULL);
}
void * udp_recvive(void *arg){
struct sockaddr_in cin;
socklen_t addrlen=sizeof(cin);
while(1){
if(recvfrom(cfd,&message,sizeof(message),0,(struct sockaddr*)&cin,&addrlen)==-1){
break;
}
if(message.type==1){
printf("%s:[%d]\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
NodePtr node=(NodePtr)malloc(sizeof(Node));
strcpy(node->username,message.username);
node->cin=cin;
node->next=head->next;
head->next=node;
}else if(message.type==2){
NodePtr p=head;
while(p->next){
if(strcmp(p->next->username,message.username)==0){
NodePtr q=p->next;
p->next=q->next;
free(q);
break;
}
p=p->next;
}
}
flag=1;
}
pthread_exit(NULL);
}
void * broadcast(void *arg){
Message message;
while(1){
strcpy(message.username,"系统广播");
printf("请输入系统广播消息:");
scanf("%s",message.text);
message.type=3;
NodePtr p=head->next;
while(p){
sendto(cfd,&message,sizeof(message),0,(struct sockaddr*)&(p->cin),sizeof(p->cin));
p=p->next;
}
printf("系统广播消息发送成功\n");
}
}
int main(int argc, const char *argv[])
{
head=(NodePtr)malloc(sizeof(Node));
head->next=NULL;
// 创建套接字
cfd = socket(AF_INET, SOCK_DGRAM, 0);
if (cfd < 0) {
perror("socket error");
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);
//bind
if(bind(cfd,(struct sockaddr*)&sin,sizeof(sin))==-1){
perror("bind error");
return -1;
}
//创建3个线程
pthread_t pid1=-1,pid2=-1,pid3=-1;
if(pthread_create(&pid1,NULL,udp_send,NULL)!=0){
perror("pthread_create error");
return -1;
}
if(pthread_create(&pid2,NULL,udp_recvive,NULL)!=0){
perror("pthread_create error");
return -1;
}
if(pthread_create(&pid3,NULL,broadcast,NULL)!=0){
perror("pthread_create error");
return -1;
}
pthread_detach(pid1);
pthread_detach(pid2);
pthread_detach(pid3);
while(1);
return 0;
}