客户端
#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");
}
}
}
}
}