基于多进程的网络聊天程序

还有点问题,做完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);

			}
		}

	}

}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值