还有点问题,做完android项目后再完善
//server.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
int current_client_num = 0;
#include "user.h"
#include "encoding.c"
#define PORT 5678
#define MAX_IP "192.168.7.255"
int getElement(char *ID); //check whether the ID exist
int Encoding(struct chat_msg *msg,char *outbuf,int size); //message's encoding
int Decoding(char *inbuf,int size,struct chat_msg *msg); //message's decoding
int main(int argc,char *argv[])
{
int sockfd,fd,newsockfd,is_connected[MAX_USER_NUM];
struct sockaddr_in addr,client_addr,maxaddr;
int client_addr_len = sizeof(struct sockaddr_in);
int addr_len = sizeof(struct sockaddr_in);
struct chat_msg cmsg,smsg;
/* create listen socket */
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(1);
}
/* fill in struct sockaddr_in */
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bzero(&maxaddr,sizeof(maxaddr));
maxaddr.sin_family = AF_INET;
maxaddr.sin_port = htons(PORT);
maxaddr.sin_addr.s_addr = inet_addr(MAX_IP);
if(bind(sockfd,(struct sockaddr*)&addr,addr_len) < 0)
{
perror("bind");
exit(1);
}
if(listen(sockfd,MAX_USER_NUM) < 0)
{
perror("listen");
exit(1);
}
fd_set readfds;
/*struct timeval tv;
int maxfd = sockfd+1,ret;
tv.tv_sec = 2;
tv.tv_usec = 0;*/
int i;
for(i=0;i<MAX_USER_NUM;i++)
{
strcpy(UserInfo[i].ID," ");
}
for(i=0;i<MAX_USER_NUM;i++)
{
is_connected[i] = 0;
;}
while(1)
{
FD_ZERO(&readfds);
FD_SET(sockfd,&readfds);
for(fd=0;fd<MAX_USER_NUM;fd++)
{
if(is_connected[fd])
FD_SET(fd,&readfds);
}
if(!(ret = select(MAX_USER_NUM,&readfds,NULL,NULL,NULL)))
{
continue;
}
for(fd=0;fd<MAX_USER_NUM;fd++)
if(FD_ISSET(fd,&readfds))
{
if(sockfd == fd)
{
/* accept new connect */
if((newsockfd = accept(sockfd,(struct sockaddr*)&client_addr.sin_addr,&client_addr_len)) < 0)
{
perror("accept");
exit(1);
}
is_connected[newsockfd] = 1;
current_client_num++;
}
else
{
char inbuf[MAX_MSG_LEN],outbuf[MAX_MSG_LEN];
bzero(inbuf,MAX_MSG_LEN);
recv(fd,inbuf,MAX_MSG_LEN,0);
Decoding(inbuf,sizeof(cmsg),&cmsg);
if(getElement(cmsg.ID) >= 0)
{
/* receive QUIT message */
if(cmsg.isQuit)
{
current_client_num--;
int index;
for(index=0;index<MAX_USER_NUM;index++)
{
if(UserInfo[index].ID == cmsg.ID)
break;
}
sprintf(UserInfo[index].ID,"%s"," ");
close(fd);
}
/* receive inquiry message */
else if(cmsg.isInquiry)
{
bzero(&smsg,sizeof(smsg));
sprintf(smsg.type,"%s","msg");
strcpy(smsg.filename," ");
strcpy(smsg.ID,"server");
sprintf(smsg.toID,"%s",cmsg.ID);
smsg.isQuit = false;
smsg.isInquiry = false;
sprintf(smsg.msg,"%s","");
int j;
for(j=0;j<current_client_num;j++)
{
strcat(smsg.msg,UserInfo[j].ID);
strcat(smsg.msg,";");
}
size_t len;
len = Encoding(&smsg,outbuf,sizeof(outbuf));
send(fd,outbuf,len,0);
}
/* retransmit message */
else
{
int ge = getElement(cmsg.toID);
if(ge < 0)
{
sprintf(smsg.type,"%s",cmsg.type);
sprintf(smsg.filename,"%s",cmsg.filename);
strcpy(smsg.ID,"server");
sprintf(smsg.toID,"%s",cmsg.ID);
smsg.isQuit = false;
smsg.isInquiry = false;
sprintf(smsg.msg,"%s","the ID:\"");
strcat(smsg.msg,cmsg.toID);
strcat(smsg.msg,"\" is not online");
size_t len;
len = Encoding(&smsg,outbuf,sizeof(outbuf));
printf("%s\n",outbuf);
send(fd,outbuf,len,0);
}
else
{
sprintf(smsg.type,"%s",cmsg.type);
sprintf(smsg.filename,"%s",cmsg.filename);
sprintf(smsg.ID,"%s",cmsg.ID);
sprintf(smsg.toID,"%s",cmsg.toID);
smsg.isQuit = false;
smsg.isInquiry = false;
sprintf(smsg.msg,"%s",cmsg.msg);
size_t len;
len = Encoding(&smsg,outbuf,MAX_MSG_LEN);
send(UserInfo[ge].fd,outbuf,len,0);
}
}
}
/* new client connect */
else
{
int index;
for(index=0;index<current_client_num;index++)
{
if(strcmp(UserInfo[index].ID," ") == 0)
break;
}
UserInfo[index].fd=fd;
sprintf(UserInfo[index].ID,"%s",cmsg.ID);
UserInfo[index].addr.sin_addr = client_addr.sin_addr;
printf("%s\n",inet_ntoa(UserInfo[index].addr.sin_addr));
UserInfo[index].addrlen = client_addr_len;
}
}
}
}
return 0;
}
//encoding.c
#include <stdio.h>
#include <string.h>
#include "msg.h"
#include <stdbool.h>
#include <stdlib.h>
char *delim_char = "#";
/* the MESSAGE's encoding and decoding */
int Encoding(struct chat_msg *msg,char outbuf[],int size)
{
char *poutbuf = outbuf;
int sz;
sz = snprintf(poutbuf,size,"%s#%s#%s#%s#%d#%d#%s#",msg->type,msg->filename,msg->ID,msg->toID,msg->isQuit,msg->isInquiry,msg->msg);
return sz;
}
int Decoding(char inbuf[],int size,struct chat_msg *msg)
{
char *token;
token = strtok(inbuf,delim_char);
if(token == 0)
return -1;
/* get type */
char buf[20];
sprintf(msg->type,"%s",token);
/* get filename */
token = strtok(NULL,delim_char);
sprintf(msg->filename,"%s",token);
/* get ID */
token = strtok(NULL,delim_char);
sprintf(msg->ID,"%s",token);
/* get toID */
token = strtok(NULL,delim_char);
sprintf(msg->toID,"%s",token);
/* get isQuit */
token = strtok(NULL,delim_char);
msg->isQuit =atoi(token);
/* get isInquiry */
token = strtok(NULL,delim_char);
msg->isInquiry = atoi(token);
/* get msg */
token = strtok(NULL,delim_char);
sprintf(msg->msg,"%s",token);
return 0;
}
//msg.h
#include <stdbool.h>
#define MAX_ID_LEN 20
#define MAX_MSG_LEN 1024
/* the message's struct */
struct chat_msg
{
char type[5]; //message's type (file,msg,reg)
char filename[20]; //if the type is file,the filename is exist
char ID[MAX_ID_LEN]; //who send the message
char toID[MAX_ID_LEN]; //send the message to whom
bool isQuit; //send the message to tell server to Quit
bool isInquiry; //send the message to inquiry server to tell ID who is online
char msg[MAX_MSG_LEN]; //message's content,or file's content
};
//user.h
#define MAX_USER_NUM 100
#define MAX_ID_LEN 20
struct record_client
{
int fd; //the client's socket
char ID[MAX_ID_LEN]; //the client's ID
struct sockaddr_in addr; //the client's IP
socklen_t addrlen;
}UserInfo[MAX_USER_NUM];
//client.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <strings.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include "encoding.c"
#define PORT 5678
/* the server's IP */
#define SERVER_IP "192.168.7.194"
int main(int argc,char *argv[])
{
int sockfd,ret;
struct chat_msg cmsg,smsg;
struct sockaddr_in addr;
int addr_len = sizeof(struct sockaddr_in);
char command[10],inbuf[MAX_MSG_LEN],outbuf[MAX_MSG_LEN];
char myID[MAX_ID_LEN];
/* build socket */
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
perror("socket");
exit(1);
}
/* fill in struct sockaddr_in */
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = inet_addr(SERVER_IP);
/* attempt to connect */
printf("you are connecting!\n");
if(connect(sockfd,(struct sockaddr*)&addr,addr_len) < 0)
{
perror("connect");
exit(1);
}
else
{
/* send user information */
strcpy(cmsg.type,"reg");
sprintf(cmsg.filename,"%s"," ");
printf("your ID:");
fscanf(stdin,"%s",cmsg.ID);
sprintf(myID,"%s",cmsg.ID);
strcpy(cmsg.toID,"server");
cmsg.isQuit = false;
cmsg.isInquiry = false;
sprintf(cmsg.msg,"%s"," ");
Encoding(&cmsg,outbuf,sizeof(cmsg));
send(sockfd,outbuf,strlen(outbuf),0);
}
fd_set readfds;
/*struct timeval tv;
tv.tv_sec = 1;
tv.tv_usec = 0;*/
while(1)
{
printf("Input your command:\n");
char buf[10];
FD_ZERO(&readfds);
FD_SET(sockfd,&readfds);
FD_SET(0,&readfds);
/* wait for the descriptor's status change */
if((ret = select(sockfd+1,&readfds,NULL,NULL,NULL) < 0))
{
perror("select");
}
/* use FD_ISSET to judge whether have data for read */
if(FD_ISSET(sockfd,&readfds))
{
bzero(inbuf,MAX_MSG_LEN);
recv(sockfd,inbuf,MAX_MSG_LEN,0);
Decoding(inbuf,MAX_MSG_LEN,&smsg);
/* a Message,receive from Server */
if(strcmp(smsg.type,"msg") == 0)
{
fprintf(stdout,"%s",smsg.msg);
} /* a File*/
else if(strcmp(smsg.type,"file") == 0)
{
int fd1;
if(strcmp(smsg.ID,"server") == 0)
{
printf("%s\n",smsg.msg);
}
else
{
fd1 = open(smsg.filename,O_WRONLY | O_CREAT,S_IRWXU);
write(fd1,smsg.msg,strlen(smsg.msg));
close(fd1);
printf("copied a file:%s\n",smsg.filename);
}
}
}
/* use FD_ISSET to judge whether have data written by keyboard */
else if(FD_ISSET(0,&readfds))
{
/* input a command */
fgets(buf,10,stdin);
/* the command is !list */
if(strncmp(buf,"!list",5) == 0)
{
strcpy(cmsg.type,"msg");
strcpy(cmsg.filename," ");
sprintf(cmsg.ID,"%s",myID);
strcpy(cmsg.toID,"server");
cmsg.isQuit = false;
cmsg.isInquiry = true;
sprintf(cmsg.msg,"%s"," ");
bzero(outbuf,MAX_MSG_LEN);
Encoding(&cmsg,outbuf,MAX_MSG_LEN);
send(sockfd,outbuf,MAX_MSG_LEN,0);
}
/* the command is !logout */
if(strncmp(buf,"!logout",7) == 0)
{
sprintf(cmsg.type,"%s","msg");
strcpy(cmsg.filename," ");
sprintf(cmsg.ID,"%s",myID);
sprintf(cmsg.toID,"%s","server");
cmsg.isQuit = true;
cmsg.isInquiry = false;
sprintf(cmsg.msg,"%s"," ");
bzero(outbuf,MAX_MSG_LEN);
Encoding(&cmsg,outbuf,MAX_MSG_LEN);
send(sockfd,outbuf,MAX_MSG_LEN,0);
exit(0);
}
/* the command is !sendmsg */printf("%s\n",inbuf);
if(strncmp(buf,"!sendmsg",8) == 0)
{
strcpy(cmsg.type,"msg");
strcpy(cmsg.filename," ");
sprintf(cmsg.ID,"%s",myID);
printf("you want to send message to whom(ID):\n");
fscanf(stdin,"%s",cmsg.toID);
cmsg.isQuit = false;
cmsg.isInquiry = false;
printf("input your send message:\n");
fscanf(stdin,"%s",cmsg.msg);
Encoding(&cmsg,outbuf,MAX_MSG_LEN);
printf("%s\n",outbuf);
send(sockfd,outbuf,strlen(outbuf),0);
}
/* the command is !sendfile */
if(strncmp(buf,"!sendfile",9) == 0)
{
strcpy(cmsg.type,"file");
sprintf(cmsg.filename,"%s","b.txt");
sprintf(cmsg.ID,"%s",myID);
printf("you want send file to whom(ID):\n");
fscanf(stdin,"%s",cmsg.toID);
cmsg.isQuit = false;
cmsg.isInquiry = false;
char filename[50];
printf("input your filename(absolute path):\n");
fscanf(stdin,"%s",filename);
int fd1;
fd1 = open(filename,O_RDONLY);
struct stat buf;
fstat(fd1,&buf);
read(fd1,cmsg.msg,sizeof(cmsg.msg));
Encoding(&cmsg,outbuf,MAX_MSG_LEN);
printf("%s\n",outbuf);
sendto(sockfd,outbuf,MAX_MSG_LEN,0,(struct sockaddr*)&addr,addr_len);
}
}
}
}