思维导图
使用tftp实现简单文件的上传
#include <head.h>
#define SER_PORT 69
#define SER_IP "192.168.125.223"
int link_file()
{
int sfd=socket(AF_INET,SOCK_DGRAM,0);
if(sfd==-1)
{
perror("socket error");
return -1;
}
return sfd;
}
int filedownload()
{
//创建文件描述符用于下载传输过来的数据包
int wfd=-1;
if((wfd=open("./copy_file",O_WRONLY|O_CREAT|O_TRUNC,0664))==-1)
{
perror("open error:");
return -1;
}
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
socklen_t socklen=sizeof(sin);
int sfd=-1;
if((sfd=link_file())==-1)
{
printf("链接失败\n");
return -1;
}
//封装请求下载数据包
//第一块
char buf[516]="";
short *p1=(short*)buf;
*p1=htons(1);
//第二模块
printf("请输入你要下载的文件:");
char file[50];
scanf("%s",file);
char *p2=buf+2;
strcpy(p2,file);
//第三模块
char *p3=p2+strlen(p2)+1;
strcpy(p3,"octet");
int len=4+strlen(p2)+strlen(p3);
sendto(sfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin));
while(1)
{
int res=0;
if((res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen))<0)
{
perror("recvfrom error:");
return -1;
}
char *data_point=buf+4;
short *cmd_point=(short*)buf;
short *block_point=(short*)(buf+2);
if(res<516)
{
write(wfd,data_point,res-4);
printf("文件拷贝完成!\n");
break;
}
write(wfd,data_point,512);
//完成了一次拷贝要向客户端发送ACK包
char ack[4];
short *p1=(short*)ack;
short *p2=(short*)(ack+2);
*p1=htons(4);
*p2=*block_point;
sendto(sfd,ack,4,0,(struct sockaddr*)&sin,sizeof(sin));
}
}
int fileonload()
{
int sfd=link_file();
system("ls");
printf("请问你要上传的文件是:");
char file[50];
scanf("%s",file);
//打开文件用于读取上传文件的数据
int send_fd=-1;
if((send_fd=open(file,O_RDONLY))==-1)
{
perror("open error:");
return -1;
}
//填充信息结构体
struct sockaddr_in sin;
sin.sin_family=AF_INET;
sin.sin_port=htons(SER_PORT);
sin.sin_addr.s_addr=inet_addr(SER_IP);
socklen_t socklen=sizeof(sin);
//封装请求下载数据包
//第一块
char buf[516]="";
short *p1=(short*)buf;
*p1=htons(2);
//第二模块
char *p2=buf+2;
strcpy(p2,file);
//第三模块 int broadcast_permission=1;
char *p3=p2+strlen(p2)+1;
strcpy(p3,"octet");
int len=4+strlen(p2)+strlen(p3);
sendto(sfd,buf,len,0,(struct sockaddr*)&sin,sizeof(sin));
char *data_point=buf+4;
short *cmd_point=(short*)buf;
*cmd_point=htons(3);
short *block_point=(short*)(buf+2);
*block_point=htons(1);
int i=1;
while(1)
{
recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&socklen);
if(*cmd_point==htons(4))
{
int res=read(send_fd,buf+4,512);
if(res==0)
{
printf("拷贝完成,按任意键退出\n");
break;
}
*cmd_point=htons(3);
sendto(sfd,buf,res+4,0,(struct sockaddr*)&sin,socklen);
}
}
}
int main(int argc, const char *argv[])
{
while(1)
{
printf("==========欢迎使用文件下载客户端==========\n");
printf("1、下载文件\t2、上传文件\t0、退出\n");
printf("请输入你要执行的操作:");
int cmd;
scanf("%d",&cmd);
switch(cmd)
{
case 1:
{
filedownload();
break;
}
case 2:
{
fileonload();
break;
}
case 0:
{
system("clear");
return 0;
}
default:
{
printf("输入有误\n");
}
}
while(getchar()=='\n');
system("clear");
}
return 0;
}