tcp多客户端多文件传输

客户端

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

enum Type
{
	TYPE_REGIST,
	TYPE_LOGIN,
	TYPE_CHAR,
	TYPE_FILE_OUT
};
typedef struct pack_t{
	enum Type type;
	char name[20];
	char pswd[20];
	char filename[64];
	long filesize;
	char ownname[20];
	char text[1024];
}pack_t;

void* thread_main(void* arg){
	int client =*(int*)arg;
	while(1){
		pack_t pack ={0};
		int res = read(client,&pack,sizeof(pack));
		if(res ==0){break;}
		switch(pack.type){
				case TYPE_REGIST:
					printf("%s\n",pack.text);
					break;
				case TYPE_LOGIN:
					printf("%s\n",pack.text);
					break;
				case TYPE_CHAR:
					printf("%s\n",pack.text);
					break;
				case TYPE_FILE_OUT:
					{

						char filename[64] = "./client/" ;
						strcat(filename,pack.filename);
						long len = pack.filesize;
						int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664);
						long read_size = 0;
						while(1)
						{
							memset(pack.text,0,sizeof(pack.text));
							read(client,&pack,sizeof(pack));
							int readed = strlen(pack.text);
							read_size += readed;
							write(fd,pack.text,strlen(pack.text));
							printf("接收中\n");
							if(read_size >= len)
							{
								break;
							}

						}
						close(fd);

					}
			   }
			}
}
int main(int argc, const char *argv[])
{
	if(argc !=2 ){
		printf("请输入端口号\n");
		return 1;
	}
	// ./server 8888
	int port = atoi(argv[1]);// 将字符串 8888 转换成int类型port


	int client = socket(AF_INET,SOCK_STREAM,0);
	addr_in_t addr = {0};
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = inet_addr("192.168.127.129");

	if(connect(client,(addr_t*)&addr,sizeof(addr)) == -1){
		perror("connect");
		return 1;
	}
	pthread_t id;
	pthread_create(&id,0,thread_main,&client);
	pthread_detach(id);
	while(1)
	{
		int flag;
		printf("1.注册\n");
		printf("2.登录\n");
		printf("3.发送消息\n");
		printf("4.发送文件\n");
		printf("5.退出\n");
		printf("请输入:");
		scanf("%d",&flag);
		switch(flag)
		{
			case 1:
				{
				pack_t pack = {0};
				pack.type = TYPE_REGIST;
				printf("请输入新账号:");
				scanf("%s",pack.name);
				printf("请输入密码:");
				scanf("%s",pack.pswd);
				write(client,&pack,sizeof(pack));
				break;
				}
			case 2:
				{
				pack_t pack = {0};
				pack.type = TYPE_LOGIN;
				printf("请输入账号:");
				scanf("%s",pack.name);
				printf("请输入密码:");
				scanf("%s",pack.pswd);
				write(client,&pack,sizeof(pack));
				break;
				}
			case 3:
				{
				pack_t pack = {0};
				pack.type = TYPE_CHAR;
				printf("请输入被发送人账号以及内容\n");
				scanf("%s %s",pack.ownname,pack.text);
				write(client,&pack,sizeof(pack));
				break;
				}
			case 4:
				{
					pack_t pack = {0};
					pack.type = TYPE_FILE_OUT;
					printf("请输入被发送人的账号:");
					scanf("%s",pack.ownname);
					while(getchar()!= 10);
					printf("请输入文件名:");
					scanf("%s",pack.filename);
					int fd = open(pack.filename,O_RDONLY);
					if(fd == -1)
					{
						printf("没有该文件\n");
						return -1;
					}
					struct stat stat_buf = {0};
					stat(pack.filename,&stat_buf);
					pack.filesize = stat_buf.st_size;
					write(client,&pack,sizeof(pack));
					long readed_size = 0;
					while(1)
					{
						memset(pack.text,0,sizeof(pack.text));
						read(fd,&pack.text,sizeof(pack.text));
						int readed = strlen(pack.text);
						write(client,&pack,sizeof(pack));
						printf("文件传输中\n");
						readed_size +=readed;
						if(readed_size >= pack.filesize)
						{
							break;
						}
					}
				}
			case 5:exit(0);

		}
	}
	return 0;
}

服务器

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;	

int find_name(const char* name);

enum Type
{
	TYPE_REGIST,
	TYPE_LOGIN,
	TYPE_CHAR,
	TYPE_FILE_OUT
};
typedef struct pack_t{
	enum Type type;
	char name[20];
	char pswd[20];
	char filename[64];
	long filesize;
	char ownname[20];
	char text[1024];
}pack_t;
typedef struct user_t{
	char user_name[20];
	char user_pswd[20];
	int user_sock_fd;
	int flagMsg;
	char Msg[1024];
	int flagFile;
	char fname[64]; //文件在服务器的文件名地址
	char file_name[64];//源文件名
}user_t;

user_t user[50] = {0};
int len = 0;
void add_name(user_t own);
void read_data(int client);
int main(int argc, const char *argv[])
{
	if(argc < 2)
	{
		printf("请输入端口号\n");
		return -1;
	}
	int port = atoi(argv[1]);
	int server_fd = socket(AF_INET,SOCK_STREAM,0);//创造服务器套接字
	
	addr_in_t addr = {0};
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = inet_addr("0.0.0.0");
	if(bind(server_fd,(addr_t*)&addr,sizeof(addr)) == -1)//将要接受信息的IP和port写入服务器套接字,并判断是否写入成功
	{
		perror("bind");
		return -1;
	}

	listen(server_fd,10);//监听,创造监听列表,将监听到的客户端存入监听列表中

	int epfd = epoll_create1(EPOLL_CLOEXEC); //创造一个动态的监视列表,并返回该列表的文件描述符
	struct epoll_event server_event = {.events=EPOLLIN,.data.fd=server_fd};
	epoll_ctl(epfd,EPOLL_CTL_ADD,server_fd,&server_event); //将服务器套接字描述符以监视是否可读的形式写入监视列表
	struct epoll_event stdin_event = {.events=EPOLLIN,.data.fd=0};
	epoll_ctl(epfd,EPOLL_CTL_ADD,0,&stdin_event);//将标准输入流的描述符写入监听列表

	struct epoll_event arr[64] = {0}; //创造一个用来保存已被激活的描述符

	while(1)
	{
		int size = epoll_wait(epfd,arr,64,-1); //监视有多少个描述符被激活,接收被激活的个数,并将激活的描述符存入到arr结构体数组中
		for(int i=0;i= len)
							{
								break;
							}
						}
						close(fd);
						user[flag].flagFile == 0;
					}
				}
				else
				{
					msg = "密码错误";
				}
				
			}
				strcpy(pack.text,msg);
				write(client,&pack,sizeof(pack));
			break;
			}
		case TYPE_CHAR:
			{
			char* msg = NULL;
			int flag = find_name(pack.ownname);
			if(flag == -1)
			{
				msg = "没有此用户";
			}
			else
			{
				int sock = user[flag].user_sock_fd;
				if(sock == 0)
				{
					msg = "该用户没登录";
					user[flag].flagMsg = 1;
					strcpy(user[flag].Msg,pack.text);
				}
				else
				{
					write(sock,&pack,sizeof(pack));
					msg = "发送成功";
				}

			}

				strcpy(pack.text,msg);
				write(client,&pack,sizeof(pack));
			break;
			}
		case TYPE_FILE_OUT:
			{
				char* msg = NULL;
				int flag = find_name(pack.ownname);
				if(flag == -1)
				{
					msg = "没有该用户";
				}
				else
				{ 
					if(user[flag].user_sock_fd == 0)
					{
						msg = "该用户处于离线状态";
						strcpy(user[flag].file_name,pack.filename);
						char filename[64] = "./server/" ;
						strcat(filename,pack.filename);
						strcpy(user[flag].fname,filename);
						user[flag].flagFile = 1;
						int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664); 
						long len = pack.filesize;
						long readed_size = 0;
						while(1)
						{
							memset(pack.text,0,sizeof(pack.text));
							read(client,&pack,sizeof(pack));
							printf("消息存入本地中\n");
							int readed = strlen(pack.text);
							write(fd,pack.text,readed);
							readed_size += readed;
							if(readed_size >= len)
							{
								break;
							}
						}
						close(fd);
					}
					else
					{
					
						
							//read(client,&pack,sizeof(pack));
							write(user[flag].user_sock_fd,&pack,sizeof(pack));
							printf("服务器发送中\n");
						
					}

				}
			}
	}
}

你可能感兴趣的:(java,网络,服务器)