服务器端
#include <stdio.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define NFDS 2
#define MSGSIZE 1025
struct customer{
char name[50];
struct sockaddr_in sin;
char msgtype;
char msgbuf[MSGSIZE];
struct customer * next;
};
struct customer * createCstmNode(){
return (struct customer *)malloc(sizeof(struct customer));
}
struct customer * insertCstmNode(struct customer * head,struct customer * newCstm){
newCstm->next=head;
head=newCstm;
return head;
}
char * getName(struct sockaddr_in sin,struct customer * head){
struct customer *p;
p=head;
while(p!=NULL){
if(p->sin.sin_addr.s_addr==sin.sin_addr.s_addr && p->sin.sin_port==sin.sin_port){
return p->name;
}
p=p->next;
}
return NULL;
}
struct customer * deleteCstmNode(struct sockaddr_in sin,struct customer * head){
struct customer * p,* q;
p=head;
q=head;
if(p==NULL){return head;}
while(p!=NULL){
if(p->sin.sin_addr.s_addr==sin.sin_addr.s_addr && p->sin.sin_port==sin.sin_port){
if(p==head){
head=p->next;
free(p);
p=NULL;
return head;
}else{
q->next=p->next;
free(p);
p=NULL;
return head;
}
}
q=p;
p=p->next;
}
return head;
}
void broadcastMsg(int skt,char * cstmName,char * msg,struct customer * head){
if(head==NULL){
printf("no client yet\n");
return;
}
if(skt<3){
printf("selected wrong socket fd\n");
return;
}
if(strlen(msg)<=0){
printf("blank message\n");
return;
}
struct customer * p=head;
while(p!=NULL){
char mb[1076]="";
strcat(mb,"[");
strcat(mb,cstmName);
strcat(mb,"]");
strcat(mb,msg);
if(sendto(skt,mb,sizeof(mb),0,(struct sockaddr *)(&(p->sin)),sizeof(p->sin))==-1){
perror("sentto error");
continue;
}
p=p->next;
}
}
int main(int argc, const char *argv[])
{
//----------create socket
int ssktfd=socket(AF_INET,SOCK_DGRAM,0);
if(ssktfd==-1){
perror("socket error");
return -1;
}
//----------form address structure
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(9999);
sin.sin_addr.s_addr=inet_addr("192.168.10.110");
//----------bind address and port to socket
if(bind(ssktfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
perror("bind error");
return -1;
}
//----------initialize customer linked list
struct customer * cstm_head=NULL;
//----------set all fds for multiplexing
struct pollfd pfds[NFDS];
for(int i=0;i<NFDS;i++){
pfds[i].fd=-1;
pfds[i].events=0;
}
pfds[0].fd=0;
pfds[0].events=POLLIN;
pfds[1].fd=ssktfd;
pfds[1].events=POLLIN;
while(1){
int res=poll(pfds,NFDS,-1);
if(res==-1){
perror("poll error");
return -1;
}else if(res==0){
printf("timeout\n");
return -1;
}
char buf[128]="";
//----------fd==0
if(pfds[0].revents==POLLIN){
scanf("%s",buf);
if(strcmp(buf,"quit")==0){
broadcastMsg(ssktfd,"server","off line",cstm_head);
break;
}else{
broadcastMsg(ssktfd,"server",buf,cstm_head);
}
}
//----------fd==ssktfd
if(pfds[1].revents==POLLIN){
char rsvMsgBuf[MSGSIZE]="";
struct sockaddr_in csin;
socklen_t len=sizeof(csin);
if(recvfrom(ssktfd,rsvMsgBuf,MSGSIZE,0,(struct sockaddr *)&csin,&len)==-1){
perror("recvfrom error");
break;
}
if(rsvMsgBuf[0]=='L'){
char * cstmName=getName(csin,cstm_head);
if(cstmName==NULL){
//----------createCstmNode();
struct customer * cstm;
cstm=createCstmNode();
//----------initialize customer node
strcpy(cstm->name,rsvMsgBuf+1);
cstm->sin=csin;
cstm->msgtype=rsvMsgBuf[0];
bzero(cstm->msgbuf,sizeof(cstm->msgbuf));
cstm->next=NULL;
//----------insert node to linked list
cstm_head=insertCstmNode(cstm_head,cstm);
//----------broadcast message
printf("[%s] log in\n",cstm->name);
broadcastMsg(ssktfd,cstm->name,"logged in",cstm_head);
}
}
if(rsvMsgBuf[0]=='C'){
//----------get customer name from linked list
char * cstmName=getName(csin,cstm_head);
if(cstmName!=NULL){
broadcastMsg(ssktfd,cstmName,rsvMsgBuf+1,cstm_head);
}
}
if(rsvMsgBuf[0]=='Q'){
char * cstmName=getName(csin,cstm_head);
if(cstmName!=NULL){
broadcastMsg(ssktfd,cstmName,"off line",cstm_head);
cstm_head=deleteCstmNode(csin,cstm_head);
printf("[%s] off line\n",cstmName);
}
}
}
}
close(ssktfd);
printf("server off line\n");
return 0;
}
客户端
#include <stdio.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#define NFDS 2
#define MSGSIZE 1025
int main(int argc, const char *argv[])
{
//----------create socket
int ssktfd=socket(AF_INET,SOCK_DGRAM,0);
if(ssktfd==-1){
perror("socket error");
return -1;
}
//----------form address structure
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(12345);
sin.sin_addr.s_addr=inet_addr("192.168.10.110");
//----------bind address and port to socket
if(bind(ssktfd,(struct sockaddr *)&sin,sizeof(sin))==-1){
perror("bind error");
return -1;
}
//----------form server address structure
struct sockaddr_in ssin;
ssin.sin_family=AF_INET;
ssin.sin_port=htons(9999);
ssin.sin_addr.s_addr=inet_addr("192.168.10.110");
//----------login
printf("please login with your name >>");
char nameBuf[50]="";
scanf(" %s",nameBuf+1);
nameBuf[0]='L';
if(sendto(ssktfd,nameBuf,sizeof(nameBuf),0,(struct sockaddr *)(&ssin),sizeof(ssin))==-1){
perror("sentto error");
return -1;
}
//----------set all fds for multiplexing
struct pollfd pfds[NFDS];
for(int i=0;i<NFDS;i++){
pfds[i].fd=-1;
pfds[i].events=0;
}
pfds[0].fd=0;
pfds[0].events=POLLIN;
pfds[1].fd=ssktfd;
pfds[1].events=POLLIN;
while(1){
int res=poll(pfds,NFDS,-1);
if(res==-1){
perror("poll error");
return -1;
}else if(res==0){
printf("timeout\n");
return -1;
}
char buf[128]="";
//----------fd==0
if(pfds[0].revents==POLLIN){
scanf("%s",buf+1);
if(strcmp(buf+1,"quit")==0){
buf[0]='Q';
if(sendto(ssktfd,buf,sizeof(buf),0,(struct sockaddr *)(&ssin),sizeof(ssin))==-1){
perror("sentto error");
return -1;
}
break;
}
buf[0]='C';
if(sendto(ssktfd,buf,sizeof(buf),0,(struct sockaddr *)(&ssin),sizeof(ssin))==-1){
perror("sentto error");
return -1;
}
}
//----------fd==ssktfd
if(pfds[1].revents==POLLIN){
char rsvMsgBuf[MSGSIZE]="";
struct sockaddr_in csin;
socklen_t len=sizeof(csin);
if(recvfrom(ssktfd,rsvMsgBuf,MSGSIZE,0,(struct sockaddr *)&csin,&len)==-1){
perror("recvfrom error");
break;
}
printf("%s\n",rsvMsgBuf);
}
}
close(ssktfd);
return 0;
}