- 用户名注册与登录
- 实现客户端通用,连接同一台服务器即可聊天;
- 能实现上下线提醒;
- 客户端查看在线列表;
- 可以传输文件;
客户端:
/*
* 客户端
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/select.h>
#include<sys/time.h>
#include<sys/stat.h>
#include<sys/ipc.h>
#include<signal.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<pthread.h>
#define SERVERIP "192.168.43.229"
#define SERVERPORT 8080
struct message //消息结构体
{
char flag[15]; //标志位
char name[20]; //用户名
char msg[1024]; //消息内容
char addressee[20]; //传输文件目的用户
int size; //传输内容的字节数
char woc[10][20];
};
struct view
{
int num;
char name[10];
};
char locname[20];
int Register(struct message a);
void log_user(struct message *a,int cfd);
int login_success(struct message a,int cfd);
int Interface();
int help(char str[]);
void handlerecvmsg(int *cfd);
void login_notice(struct message buf,int cfd);
void leave_notice(struct message buf,int cfd);
void send_allpeople(struct message a,int cfd);
void send_personal(struct message a,int connfd);
void send_file(int cfd,char *name);
void recv_file(struct message msg,int cfd);
int main(void)
{
struct message a;
struct message msg;
int cfd;
time_t timep;
//连接服务器
cfd=socket(AF_INET,SOCK_STREAM,0);
perror("socket");
struct sockaddr_in saddr;
bzero(&saddr,sizeof(struct sockaddr_in)); //清空地址结构
saddr.sin_family=AF_INET;
saddr.sin_port=htons(SERVERPORT);
saddr.sin_addr.s_addr=inet_addr(SERVERIP);
//connect(cfd,(const struct sockaddr*)&saddr,sizeof(struct sockaddr));
//perror("connect");
while(1)
{
//界面
int num;
num=Interface();
switch (num)
{
case 1://注册
{
Register(a);
break;
}
case 2://登录
connect(cfd,(const struct sockaddr*)&saddr,sizeof(struct sockaddr));
perror("connect");
printf("cfd:%d\n",cfd);
log_user(&a,cfd);
if(strcmp(a.msg,"login,success!")==0)
{
while(1)
{
login_success(a,cfd);
}
}
exit(3);
break;
case 3://退出
{
close(cfd);
printf("离开聊天室!\n");
exit(1);
break;
}
default:
{
break;
}
}
}
close(cfd);
return 0;
}
/*
* 函数名:Register
* 功能:注册
* 传入参数:struct message a
* 返回值:0
*/
int Register(struct message a)
{
int ccfd;
ccfd=socket(AF_INET,SOCK_STREAM,0);
perror("socket");
struct sockaddr_in saddr;
bzero(&saddr,sizeof(struct sockaddr_in)); //清空地址结构
saddr.sin_family=AF_INET;
saddr.sin_port=htons(SERVERPORT);
saddr.sin_addr.s_addr=inet_addr(SERVERIP);
connect(ccfd,(const struct sockaddr*)&saddr,sizeof(struct sockaddr));
perror("connect");
char password_t[20];
printf("请输入用户名(10字以内):\n");
memset(a.name,0,strlen(a.name));
scanf("%s",a.name);
while(1)
{
printf("请输入密码(20位以内):\n");
memset(a.msg,0,strlen(a.msg));
scanf("%s",a.msg);
printf("请再次输入密码:\n");
memset(password_t,0,strlen(password_t));
scanf("%s",password_t);
if(strcmp(a.msg,password_t)!=0 || strlen(a.msg)>20 || strlen(password_t)>20)
{
printf("密码错误!\n");
}
else
{
break;
}
}
strcpy(a.flag,"reg");
printf("%d\n",ccfd);
send(ccfd,&a,sizeof(struct message),0);
printf("正在注册,请稍后.....\n");
recv(ccfd,&a,sizeof(struct message),0);
printf("recv the message from server:%s\n",a.msg);
close(ccfd);
sleep(1);
}
/*
* 函数名: log_user
* 功能: 用户登录
* 传入参数:struct message *a,int cfd
* 返回值: 无
*/
void log_user(struct message *a,int cfd)
{
printf("请输入用户名(10字以内):\n");
memset(a->name,0,strlen(a->name));
scanf("%s",a->name);
strcpy(locname,a->name);
printf("请输入密码(20位以内):\n");
memset(a->msg,0,strlen(a->msg));
scanf("%s",a->msg);
strcpy(a->flag,"login");
send(cfd,a,sizeof(*a),0);
printf("正在登录,请稍后....\n");
recv(cfd,a,sizeof(*a),0);
printf("%s\n",a->msg);
}
/*
* 函数名: login_success
* 功能: 登录成功进入聊天模式
* 传入参数: struct message *a,int cfd
* 返回值: 退出返回0,否则返回1
*/
int login_success(struct message a,int cfd)
{
char str[1024];
char buf[1024];
time_t timep;
pthread_t pid;
pthread_create(&pid,NULL,(void *)handlerecvmsg,(void *)&cfd);//创建接受消息线程
system("clear");
login_notice(a,cfd); //上线通知
printf("尊敬的%s你好,如需帮助请输入:.help\n",locname);
while(1)
{
memset(a.msg,0,strlen(a.msg));
memset(str,0,strlen(str));
printf("TO:\n");
scanf("%s",str);
if(1==help(str)) //提示信息
{
continue;
}
strcpy(a.name,locname);
strcpy(a.flag,str);
if(strcmp(a.flag,"exit")==0)
{
leave_notice(a,cfd);
send(cfd,&a,sizeof(struct message),0);
exit(0);
}
else if(strcmp(a.flag,"view")==0)
{
send(cfd,&a,sizeof(struct message),0); //请求查看在线用户
continue;
}
else if(strcmp(a.flag,"all")==0)
{
send_allpeople(a,cfd);
continue;
}
else if(strcmp(a.flag,"tran")==0)
{
printf("===选择你要发送的用户====\n");
scanf("%s",a.name);
send_file(cfd,a.name);
}
else if(strcmp(a.flag,"personal")==0)
{
send_personal(a,cfd);
continue;
}
else
continue;
}
}
/*
* 函数名:Interface
* 功能:登录界面
* 传入参数:无
* 返回值:do_number
*/
int Interface()
{
int do_number;
do
{
system("clear");
printf("\n====================");
printf("\n===欢迎进入聊天室===");
printf("\n======1.注册========");
printf("\n======2.登录========");
printf("\n======3.退出========");
printf("\n====================\n");
printf("选择你要执行的功能(1-3):");
scanf("%d",&do_number);
}while((do_number!=1)&&(do_number!=2)&&(do_number!=3));
return do_number;
}
/*
* 函数名:help
* 功能:帮助
* 传入参数:char str[]
* 返回值:成功返回1,否则返回0
*/
int help(char str[])
{
if(strcmp(str,".help")==0)
{
system("clear");
printf("=========================================\n");
printf("尊敬的%s用户,你好:\n",locname);
printf("all$------------------对所有人说\n");
printf("view$-----------------查看在线用户\n");
printf("tran$-----------------发送文件\n");
printf("personal$-------------私聊\n");
printf("exit$-----------------退出\n");
printf("=========================================\n");
return 1;
}
else
return 0;
}
//上线通知
void login_notice(struct message buf,int cfd)
{
char info[]="来到本聊天室!";
strcpy(buf.flag,"all");
strcpy(buf.msg,info);
send(cfd,&buf,sizeof(struct message),0);
}
//下线通知
void leave_notice(struct message buf,int cfd)
{
char info[]="离开本聊天室!";
strcpy(buf.flag,"all");
strcpy(buf.msg,info);
send(cfd,&buf,sizeof(struct message),0);
}
/*
* 函数名:handlerecvmsg
* 功能:消息接受
* 传入参数:int *sfd
* 返回值:无
*/
void handlerecvmsg(int *sfd)
{
int connfd=*sfd;
int nread;
int fd;
char buf[1024];
char str[1024];
struct message recvmsg;
time_t timep;
if((fd=open("chat_log.dat",O_RDWR|O_CREAT|O_APPEND,0777))<0) //创建聊天记录文件
{
printf("打开聊天记录失败!\n");
exit(1);
}
while(1)
{
nread=recv(connfd,&recvmsg,sizeof(struct message),0);//接受文件
if(nread==0)
{
printf("You have detached from the server!\n");
close(fd);
exit(0);
}
else if(strcmp(recvmsg.flag,"all")==0) //接受群发消息
{
time(&timep);
memset(str,0,strlen(str));
sprintf(str,"%s%s说:%s\n",ctime(&timep),recvmsg.name,recvmsg.msg);
printf("%s",str);
write(fd,str,strlen(str));
}
else if(strcmp(recvmsg.flag,"personal")==0) //接收私聊消息
{
time(&timep);
memset(str,0,strlen(str));
sprintf(str,"%s%s对你说:%s\n",ctime(&timep),recvmsg.name,recvmsg.msg);
printf("%s",str);
write(fd,str,strlen(str));
}
else if(strcmp(recvmsg.flag,"tran")==0) //文件传输
{
recv_file(recvmsg,connfd);
}
else if(strcmp(recvmsg.flag,"view")==0) //查看在线人数
{
int i=0;
printf("目前在线%d人!\n",recvmsg.size);
for(i;i<recvmsg.size;i++)
{
printf("%s\n",recvmsg.woc[i]);
}
}
/* else if(strcmp(recvmsg.flag,"ask")==0)
{
if(strcpy(recvmsg.msg,"1")==0)
{
printf("文件接收成功!\n");
}
else
printf("对方没有接收文件!\n");
} */
}
}
/*
* 函数名:send_allpeople()
* 功能:给所以人发送信息
* 传入参数:struct message a, int cfd
* 返回值:无
*/
void send_allpeople(struct message a,int cfd)
{
system("clear");
printf("======对所有人说=======\n");
printf("请输入你要说的话:\n");
scanf("%s",a.msg);
send(cfd,&a,sizeof(struct message),0);
}
/*
* 函数名:send_personal
* 功能:私发消息
* 传入参数:struct message a,int connfd
* 返回值:无
*/
void send_personal(struct message a,int connfd)
{
system("clear");
printf("=========私聊===========\n");
printf("请输入你要聊天的对象:\n");
scanf("%s",a.name);
printf("请输入你想说的话:\n");
scanf("%s",a.msg);
send(connfd,&a,sizeof(struct message),0);
}
/*
* 函数名:send_file()
* 功能:发送文件
* 传入参数:int cfd,char *name
* 返回值:无
*/
void send_file(int cfd,char *name)
{
int fp;
int size;
int ret;
struct message filedata;
struct stat buf_st;
strcpy(filedata.name,name);
strcpy(filedata.flag,"tran");
strcpy(filedata.addressee,locname);
fp=open("./pig.txt",O_RDWR);
if(fp<0)
{
printf("文件打开失败!\n");
exit(0);
}
ret=stat("./pig.txt",&buf_st); //获取文件的大小 保存到buf_st所指的结构体成员st_size中
if(ret<0)
{
perror("stat");
return ;
}
size=buf_st.st_size;
filedata.size=size;
send(cfd,&filedata,sizeof(filedata),0);
while(1)
{
ret=read(fp,filedata.msg,1024);
send(cfd,filedata.msg,ret,0);
bzero(filedata.msg,sizeof(filedata.msg));
if(ret!=1024)
{
break;
}
}
close(fp);
printf("发送完成!\n");
}
/*
* 函数名:recv_file()
* 功能:接收文件
* 传入参数:struct message msg,int cfd
* 返回值:无
*/
void recv_file(struct message msg,int cfd)
{
int filenum1=0;
int filenum2=0;
int writelen=0;
int realen=0;
int sum=0;
float percent=0;
int i;
printf("正在接收%s发来的文件....\n",msg.name);
int fd=open("./cat.txt",O_WRONLY | O_CREAT | O_TRUNC | O_APPEND);
if(fd<0)
{
perror("Receive_files open");
return;
}
filenum1=msg.size/1024;
filenum2=msg.size%1024;
//发送应答
send(cfd,"ACK",strlen("ACK"),0);
if(filenum1==0)//小于1000
{
realen=recv(cfd,msg.msg,sizeof(msg.msg),0);
writelen=write(fd,msg.msg,realen);
bzero(msg.msg,sizeof(msg.msg));
sum=sum+writelen;
percent=(float)1.0*sum/msg.size;
percent=percent*100;
printf("完成度:%d/%d %0.2f%c\n",sum,msg.size,percent,'%');
}
else if((filenum1>0)&&(filenum2==0))//BUFSIZ整数倍
{
for(i=0;i<filenum1;i++)
{
realen=recv(cfd,msg.msg,sizeof(msg.msg),0);
writelen=write(fd,msg.msg,realen);
bzero(msg.msg,sizeof(msg.msg));
sum=sum+writelen;
percent=(float)1.0*sum/msg.size;
percent=percent*100;
printf("完成度:%d/%d %0.2f%c\n",sum,msg.size,percent,'%');
}
}
else if((filenum1>0)&&(filenum2!=0))//BUFSIZ整数倍+多余部分
{
for(i=0;i<filenum1+1;i++)
{
realen=recv(cfd,msg.msg,sizeof(msg.msg),0);
writelen=write(fd,msg.msg,realen);
bzero(msg.msg,sizeof(msg.msg));
sum=sum+writelen;
percent=(float)1.0*sum/msg.size;
percent=percent*100;
printf("完成度:%d/%d %0.2f%c\n",sum,msg.size,percent,'%');
}
}
printf("接收完成!\n");
close(fd);
}
服务器:
/*
* 聊天群服务器端
*/
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/stat.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<time.h>
#include<errno.h>
#include<pthread.h>
#define PEOPLE 10 //宏定义监视的人数
#define SERVERIP "192.168.43.229"//宏定义ip地址
#define SERVERPORT 8080 //宏定义端口号
typedef struct list //消息结构体
{
char flag[15]; //标志位
char name[20]; //用户名
char msg[1024]; //消息内容
char addressee[20]; //传输文件目录用户
int size; //传输内容字节数
struct list *next;
}LIST;
LIST *lhead=NULL;
typedef struct decr
{
int decr;
char name[20];
struct decr *next;
}DECR;
DECR *phead=NULL;
struct message //消息结构体
{
char flag[15]; //标志位
char name[20]; //用户名
char msg[1024]; //消息内容
char addressee[20]; //传输文件目录用户
int size; //传输内容字节数
char woc[10][20];
};
DECR *creat_decr();
LIST *creat_list();
int add_list(char *name,char *msg);
int find_list(char *name);
int reg_check(struct message buf);
int login_check(char *name,char *msg);
int server_reg(struct message buf,int cfd);
int server_view(struct message *a);
int server_exit(int decr);
int server_login(struct message buf,int cfd);
int server_all(struct message buf,int connfd);
void server_personal(struct message a,int cfd);
void handlerecvmsg(int *sfd);
int add_decr(int decr,char *name);
int find_decr(char *name);
void find_name(int decr,struct message *a);
void send_file(struct message a,int cfd,int sfd);
int main(int argc,char *argv[])
{
struct message buf;
struct sockaddr_in caddr;
struct sockaddr_in saddr;
socklen_t addrlen=sizeof(struct sockaddr);
int lfd; //保存服务器套接字
int cfd; //保存客户端套接字
int sfd;
pthread_t tid=0;
int re;
fd_set set;
time_t timep;
//创建套接字
lfd=socket(AF_INET,SOCK_STREAM,0);
perror("socket");
//绑定端口
saddr.sin_family=AF_INET;
saddr.sin_port=htons(SERVERPORT);
saddr.sin_addr.s_addr=inet_addr(SERVERIP);
bind(lfd,(const struct sockaddr*)&saddr,sizeof(struct sockaddr));
perror("bind");
//设置监听数量
listen(lfd,PEOPLE);
perror("listen");
printf("正在连接....\n");
//开始服务器程序的死循环
while(1)
{
FD_ZERO(&set);
FD_SET(lfd,&set);
select(lfd+1,&set,NULL,NULL,NULL);
if(FD_ISSET(lfd,&set))
{
cfd=accept(lfd,(struct sockaddr*)&caddr,&addrlen);
if(cfd<0)
{
perror("accept");
}
else
{
recv(cfd,&buf,sizeof(buf),0);
if(strcmp(buf.flag,"login")==0) //客户端请求登录
{
add_decr(cfd,buf.name);
server_login(buf,cfd); //处理登录请求
pthread_create(&tid,NULL,(void *)handlerecvmsg,(void *)&cfd);//创建线程
pthread_detach(tid);
continue;
}
else if(strcmp(buf.flag,"reg")==0) //处理注册请求
{
server_reg(buf,cfd);
}
}
}
}
//pthread_mutex_destory(&mutex);
close(lfd);
return 0;
}
//创建链表
LIST *creat_list()
{
// return calloc(sizeof(struct list),1);
return (LIST *) malloc(sizeof(struct list));
}
DECR *creat_decr()
{
return (DECR *) malloc(sizeof(struct decr));
}
//添加链表
int add_list(char *name,char *msg)
{
FILE *fp;
LIST *p=lhead;
if(p==NULL)
{
LIST *tmp=creat_list();
p=tmp;
lhead=tmp;
tmp->next=NULL;
strcpy(tmp->name,name);
strcpy(tmp->msg,msg);
fp=fopen("./name.dat","a+b");
fwrite(tmp,sizeof(struct list),1,fp);
fclose(fp);
}
else
{
while(p->next!=NULL)
{
p=p->next;
}
LIST *tmp=creat_list();
p->next=tmp;
strcpy(tmp->name,name);
strcpy(tmp->msg,msg);
tmp->next=NULL;
fp=fopen("./name.dat","a+b");
fwrite(tmp,sizeof(struct list),1,fp);
fclose(fp);
}
return 0;
}
//查找链表中是否有目标用户
int find_list(char *name)
{
FILE *fp;
fp=fopen("./name.dat","rb");
LIST *p=lhead;
while(!feof(fp))
{
LIST *p1=creat_list();
fread(p1,sizeof(struct list),1,fp);
if(p==NULL)
{
p=p1;
lhead=p1;
p1->next=NULL;
}
else
{
while(p->next!=NULL)
{
p=p->next;
}
p->next=p1;
p1->next=NULL;
}
}
p=lhead;
while(p!=NULL)
{
if(strcmp(p->name,name)==0)
{
return 1;
}
p=p->next;
}
fclose(fp);
return 0; //不存在返回0
}
/*
*函数名:reg_check
*功能:检查注册函数
*传入参数:struct message buf
*返回值:成功返回1;否则返回0
*/
int reg_check(struct message buf)
{
int i;
i=find_list(buf.name);
if(i=1)
{
add_list(buf.name,buf.msg);
return 1;
}
return 0;
}
/*
* 函数名:login_check
* 功能:检查登录用户名和密码
* 传入参数:char *name,char *name
* 返回值:成功返回1;否则返回0
*/
int login_check(char *name,char *msg)
{
FILE *fp;
fp=fopen("./name.dat","rb");
LIST *p=lhead;
while(!feof(fp))
{
LIST *p1=creat_list();
fread(p1,sizeof(struct list),1,fp);
if(p==NULL)
{
p=p1;
lhead=p1;
p1->next=NULL;
}
else
{
while(p->next!=NULL)
{
p=p->next;
}
p->next=p1;
p1->next=NULL;
}
}
p=lhead;
while(p!=NULL)
{
if((strcmp(p->name,name)==0)&&(strcmp(p->msg,msg)==0))
{
return 1;
}
p=p->next;
}
fclose(fp);
return 0;
}
/*
*函数名:server_reg
*功能:客户端注册处理
*传入参数:struct message buf,int cfd
*返回值:无
*/
int server_reg(struct message buf,int cfd)
{
int i;
i=reg_check(buf);
if(i==1)
{
printf("%s注册成功!\n",buf.name);
strcpy(buf.msg,"register,success!");
send(cfd,&buf,sizeof(struct list),0);
}
else
{
printf("%s登录失败!\n",buf.name);
strcpy(buf.msg,"register,failure!");
send(cfd,&buf,sizeof(struct list),0);
}
}
/*
*函数名: server_view
*功能: 处理客户端查看当前在线用户
*传入参数:struct message *a
*返回值: i
*/
int server_view(struct message *a)
{
int i=0;
DECR *p=phead;
while(p!=NULL)
{
strcpy(a->woc[i],p->name);
p=p->next;
i++;
}
a->size=i;
return i;
}
/*
* 函数名:server_exit
* 功能:处理客户端与服务器断开连接
* 传入参数:int decr
* 返回值:无
*/
int server_exit(int decr)
{
DECR *p,*q,*s;
p=phead;
q=phead->next;
while(q)
{
if(q->decr==decr)
{
p->next=q->next;
s=q;
q=q->next;
free(s);
}
else
{
p=p->next;
q=q->next;
}
}
return 0;
}
/*
* 函数名:server_login
* 功能:处理客户端登录
* 传入参数:struct message buf,int cfd
* 返回值:无
*/
int server_login(struct message buf,int cfd)
{
int i;
i=login_check(buf.name,buf.msg);
if(i==1)
{
printf("%s登录成功!\n",buf.name);
memset(buf.msg,0,strlen(buf.msg));
strcpy(buf.msg,"login,success!");
send(cfd,&buf,sizeof(struct list),0);
sprintf(buf.msg,"欢迎%s进入聊天室!",buf.name);
}
}
/*
* 函数名:server_personal
* 功能:处理客户端私聊
* 传入参数:struct message a,int cfd
* 返回值:成功返回1,否则返回0
*/
void server_personal(struct message a,int cfd)
{
int decr=0;
decr=find_decr(a.name);
find_name(cfd,&a);
send(decr,&a,sizeof(struct message),0);
}
/*
* 函数名:server_all
* 功能:处理客户端群发
* 传入参数:struct message buf,int connfd
* 返回值:1
*/
int server_all(struct message buf,int connfd)
{
if(strcmp(buf.msg,"")!=0)
{
DECR *p=phead;
while(p!=NULL)
{
connfd=p->decr;
send(connfd,&buf,sizeof(struct message),0);
p=p->next;
}
}
}
/*
* 函数名:handlerecvmsg()
* 功能: 线程处理接收到客户端的命令
* 传入参数:int *sfd
* 返回值:
*/
void handlerecvmsg(int *sfd)
{
int connfd=*sfd;
int nread;
struct message recvmsg;
while(1)
{
nread=recv(connfd,&recvmsg,sizeof(struct message),0);
if(nread==0)
{
printf("You have detached from the client!\n");
exit(0);
}
if(strcmp(recvmsg.flag,"all")==0)
{
server_all(recvmsg,connfd);
}
else if(strcmp(recvmsg.flag,"view")==0)
{
server_view(&recvmsg);
send(connfd,&recvmsg,sizeof(struct message),0);
}
else if(strcmp(recvmsg.flag,"exit")==0)
{
server_exit(connfd);
pthread_exit(NULL);
}
else if(strcmp(recvmsg.flag,"personal")==0)
{
server_personal(recvmsg,connfd);
}
else if(strcmp(recvmsg.flag,"tran")==0)
{
int cfd;
cfd=find_decr(recvmsg.name);
send_file(recvmsg,cfd,connfd);
}
else if(strcmp(recvmsg.flag,"ask")==0)
{
int cfd;
cfd=find_decr(recvmsg.name);
send(cfd,&recvmsg,sizeof(struct message),0);
}
}
}
/*
* 函数名:add_decr()
* 功能:添加套接字到链表
* 传入参数:int decr,char *name
* 返回值:无
*/
int add_decr(int decr,char *name)
{
DECR *p=phead;
if(p==NULL)
{
DECR *tmp=creat_decr();
p=tmp;
phead=tmp;
tmp->next=NULL;
tmp->decr=decr;
strcpy(tmp->name,name);
}
else
{
while(p->next!=NULL)
{
p=p->next;
}
DECR *tmp=creat_decr();
p->next=tmp;
tmp->decr=decr;
strcpy(tmp->name,name);
tmp->next=NULL;
}
}
/*
* 函数名:find_decr
* 功能:查找目标人的套接字
* 传入参数:char *name
* 返回值:p->decr
*/
int find_decr(char *name)
{
int i=0;
DECR *p=phead;
while(p!=NULL)
{
if((strcmp(p->name,name))==0)
{
i=p->decr;
return i;
}
p=p->next;
}
}
/*
* 函数名:find_name
* 功能:查找套接字的目标人
* 传入参数:int decr,struct message *a
* 返回值:无
*/
void find_name(int decr,struct message *a)
{
DECR *p=phead;
while(p!=NULL)
{
if(p->decr==decr)
{
strcpy(a->name,p->name);
}
p=p->next;
}
}
/*
* 函数名:send_file()
* 功能:发送文件
* 传入参数:struct message a,int cfd,int sfd
* 返回值:p->decr
*/
void send_file(struct message a,int cfd,int sfd)
{
char askflag[10];
int filenum1=0;
int filenum2=0;
int i;
struct message b;
struct message c;
bzero(&b,sizeof(b)); //清理空间
filenum1=a.size/1000;
filenum2=a.size%1000;
strcpy(b.name,a.addressee);
strcpy(b.flag,a.flag);
strcpy(b.addressee,a.name);
b.size=a.size;
send(cfd,&b,sizeof(b),0);
//等待客户端应答
/* while(1)
{
printf("====\n");
recv(cfd,askflag,sizeof(askflag),0);
printf("%s\n",askflag);
if(strstr(askflag,"ACK")!=NULL)
{printf("123456\n");
break;
}
} */
int realen=0;
if(filenum1==0) //小于1000
{
bzero(b.msg,sizeof(b.msg));
bzero(c.msg,sizeof(c.msg));
realen=recv(sfd,c.msg,sizeof(c.msg),0);
strcpy(b.msg,c.msg);
send(cfd,b.msg,realen,0);
}
else if((filenum1>0) && (filenum2==0)) //整数倍
{
for(i=0;i<filenum1;i++)
{
bzero(b.msg,sizeof(b.msg));
bzero(c.msg,sizeof(c.msg));
realen=recv(sfd,c.msg,sizeof(c.msg),0);
strcpy(b.msg,c.msg);
send(cfd,b.msg,realen,0);
}
}
else if((filenum1>0) && (filenum2!=0)) //整数倍+多余
{
for(i=0;i<filenum1+1;i++)
{
bzero(b.msg,sizeof(b.msg));
bzero(c.msg,sizeof(c.msg));
realen=recv(sfd,c.msg,sizeof(c.msg),0);
strcpy(b.msg,c.msg);
send(cfd,b.msg,realen,0);
}
}
return;
}