📄 chatclient.c
字号:
//每个用户维护自己的用户列表//使用tcp与服务器连接,获取用户信息//然后从一个udp端口监听其他用户的消息和服务器的更新消息#include <stdio.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/types.h>#include <arpa/inet.h>#include <string.h>#include <signal.h>#include <pthread.h>#define SERV_PORT 7000 //server的tcp端口#define SUDP_PORT 7001 //server的udp端口#define err_sys printf#define MAXSIZE 5000//#define CLET_PORT 2029 #define MESG_PORT 7002//#define MESG_PORT 2031#define MAXLINE 500#define NAMELEN 20#define LEN sizeof(user)typedef struct _user{ char name[NAMELEN]; char ip[16]; struct _user *next; struct _user *prev;}user;static user *head;user *tail;user *p;user *q;int lock;int usrnum;int wait;char Myname[NAMELEN];void add(char * buffer,int type){ int i; while(lock==1) i++; lock=1; if(buffer[0]=='\0') return; char *t; char *c; char *s; char *buf=buffer; if((buffer[0]=='+')||(buffer[0]=='-')) buf=buffer+1; while((t=strchr(buf,'\r'))!=NULL) { if(head==NULL) { p=tail=head=(user *)malloc(LEN); head->prev=head->next=NULL; } else { p=(user *)malloc(LEN); tail->next=p; p->prev=tail; p->next=NULL; tail=p; } t[0]='\0'; strcpy(p->name,buf); buf=t+1; t=strstr(buf,"\r\r"); strncpy(p->ip,buf,t-buf); p->ip[t-buf]='\0'; buf=t+2; usrnum++; } if(type==1) printf("\nA new comer: \t%s\n",p->name); fflush(stdout);}void UserList(){ int i; while(lock==1) i++; lock=1; if(head==NULL) { printf("No User except yourself!\n\n\n"); return; } printf("\nThe user list:\n"); printf("\tName"); printf("\t\t\t IP\n"); for(p=head;p!=NULL;p=p->next) { printf("\t%-15s",p->name); printf("\t %-20s\n",p->ip); }}user *find(char *buf,int i){ p=head; while(p!=NULL) { if(strcmp((i==1)?p->ip:p->name,buf)==0) return p; p=p->next; } return NULL;}void del(char *buffer){ int i; char *s; while(lock==1) i++; lock=1; char buf[20]; s=strchr(buffer,'\r'); strncpy(buf,buffer+1,s-buffer-1); buf[s-buffer-1]='\0'; user *result=find(buf,1); if(result==NULL) return; if(head==NULL) return; printf("\n%s has left!\n",result->name); fflush(stdout); if((result->prev==NULL)||(result==head)) { head=result->next; if(head!=NULL) head->prev=NULL; } else if(result->next==NULL) { tail=result->prev; tail->next=NULL; } else { result->prev->next=result->next; result->next->prev=result->prev; } free(result);}int sock;pthread_t udplisten_t;void *udpserver(void){ //upd监听 struct sockaddr_in servaddr, cliaddr; sock = socket(AF_INET, SOCK_DGRAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(MESG_PORT); if(bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) { perror("udp bind error"); exit(1); } char buf[MAXLINE]; int buflen; ssize_t len; while(1) { buflen = sizeof(buf); bzero(buf,buflen); bzero(&cliaddr,sizeof(cliaddr)); len = sizeof(cliaddr); recvfrom(sock, buf,MAXLINE, 0,(struct sockaddr*)&cliaddr, &len); if(buf[0]=='+') { // lock=1; // printf("Recev: %s",buf); add(buf,1); lock=0; } else if(buf[0]=='-') { // lock=1; del(buf); lock=0; } else { p=find(inet_ntoa(cliaddr.sin_addr),1); int i; while(wait==1) i++; if(p==NULL) printf("Not in the session!\n"); printf("\nMsg from: %s\nThe msg:%s\n\n",p->name,buf); fflush(stdout); } }}char serverip[20];static void closed(){ close(sock); char buf[1]; struct sockaddr_in servaddr; int sockfd; buf[0]='-'; bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SUDP_PORT); inet_aton(serverip, &servaddr.sin_addr); sockfd = socket(AF_INET, SOCK_DGRAM, 0); int len=sizeof(servaddr); sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&servaddr,len); exit(0);}void Broadcast(){ struct sockaddr_in servaddr; char msg[MAXLINE]; char ip[16]; int sockfd; printf("please input the message you want to broadcast:"); fgets(msg,MAXLINE,stdin); if(strcmp(head->name,Myname)==0) { printf("No user except yourself"); return; } for(p=head;p!=NULL;p=p->next) { if(strcmp(p->name,Myname)==0) continue; strcpy(ip,p->ip); bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(MESG_PORT); inet_aton(ip,&servaddr.sin_addr); sockfd=socket(AF_INET,SOCK_DGRAM,0); sendto(sockfd,msg,sizeof(msg),0,(struct sockaddr*)&servaddr,sizeof(servaddr)); close(sockfd);}}void Chat(){ char chatname[NAMELEN]; char msg[MAXLINE]; char ip[16]; int sockfd,n,buflen,ret; struct sockaddr_in servaddr; int len; printf("\nplease input the name of user you want to chat with:"); scanf("%s",chatname); getchar(); p=find(chatname,0); if(p==NULL) printf("No this user!\n"); // else if(strcmp(p->name,Myname)==0) // exit(0); else { strcpy(ip,p->ip); wait=1; printf("Please input your message:"); fgets(msg,MAXLINE,stdin); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MESG_PORT); inet_aton(ip,&servaddr.sin_addr); sockfd = socket(AF_INET, SOCK_DGRAM, 0); len=sizeof(servaddr); sendto(sockfd, msg, sizeof(msg), 0, (struct sockaddr *)&servaddr, len); wait=0; close(sockfd);}}void Quit(char *argv){ struct sockaddr_in servaddr; char buf[1]; int sockfd; buf[0]='-'; bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SUDP_PORT); inet_aton(argv, &servaddr.sin_addr); sockfd = socket(AF_INET, SOCK_DGRAM, 0); int len=sizeof(servaddr); sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&servaddr,len); close(sockfd); exit(0); }int main(int argc, char **argv){ signal(SIGINT,closed); int sockfd,n,buflen,ret; char buffer[MAXSIZE+1]; struct sockaddr_in servaddr; // fd_set read_set; usrnum=0; head=tail=NULL; wait=0; if(argc<2) { printf("Useage : %s [server ip]\n",argv[0]); return 1; } strcpy(serverip,argv[1]); ret=pthread_create(&udplisten_t,NULL,(void *)udpserver,NULL); struct timeval timeout; if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { err_sys("socket error\n"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERV_PORT); n=inet_aton(argv[1],&servaddr.sin_addr); if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { printf("The Server has not start!\n"); exit(1); } printf("Please input the name you will use:\n"); fflush(stdout); scanf("%s",Myname); ret = send(sockfd,Myname,strlen(Myname),0); if(buflen=recv(sockfd,buffer,sizeof(buffer),0)<0) { printf("Wrong!\n"); exit(1); } add(buffer,0); lock=0; UserList(); fflush(stdout); lock=0; int choice; while(1) { printf("\nchoices:\n"); printf("1:show all users.\n"); printf("2:chat with one user.\n"); printf("3:broadcast.\n"); printf("4:exit.\n"); scanf("%d",&choice); getchar(); switch(choice) { case 1 : UserList(); lock=0; break; case 2 : Chat(); break; case 3 : Broadcast(); break; case 4 : Quit(argv[1]); break; default:printf("wrong choice; please rechoose!\n"); break; }//switch }//while close(sock);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -