基于UDP的tftp的传输协议
下载
#include
#define PORT 69 //服务器端口号,范围1024-49151
#define IP "192.168.114.161" //服务器IP,发给谁就填谁的IP
int do_download(int cfd,struct sockaddr_in sin);
int main(int argc, const char *argv[])
{
//创建报式套接字文件
int cfd;
if((cfd = socket(AF_INET,SOCK_DGRAM,0))<0)
{
ERR_MSG("socket create error");
return -1;
}
printf("socket create success cfd = %d\n",cfd);
//填充绑定本机的地址信息
struct sockaddr_in sin;
sin.sin_family =AF_INET;
sin.sin_port =htons(PORT);
sin.sin_addr.s_addr =inet_addr(IP);
char choose =0;
//菜单
while(1)
{
system("clear");
printf("--------------------------------\n");
printf("-----------1. 下载--------------\n");
printf("-----------2. 上传--------------\n");
printf("-----------3. 退出--------------\n");
printf("--------------------------------\n");
printf("请输入>>>>");
scanf("%c",&choose);
while(getchar()!=10); //循环吸收垃圾字符
int flag =1;
switch(choose)
{
case '1':
//下载
do_download(cfd,sin);
break;
case '2':
//上传
//do_upload(cfd,sin);
break;
case '3':
flag = 0;
break;
default:
printf("输入错误,请重新输入");
break;
}
if(flag == 0)
{
break;
}
printf("输入任意字符清屏>>>>\n");
while(getchar()!=10);
}
//关闭套接字
close(cfd);
return 0;
}
int do_download(int cfd,struct sockaddr_in sin)
{
char buf[516] ="";
char filename[20]= "";
printf("请输入要下载的文件名>>");
scanf("%s",filename);
while(getchar()!=10);
//组下载请求包
//操作码
unsigned short *ptr1=(unsigned short *)buf;
*ptr1 =htons(1);
//文件名
char *ptr2 = buf+2;
strcpy(ptr2,filename);
//模式
char * ptr4 = ptr2 +strlen(filename)+1;
strcpy(ptr4,"octet");
//发送下载请求 sendto
int size = 2+strlen(ptr2)+1+strlen(ptr4)+1;
if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto error");
return -1;
}
printf("sendto download request success\n");
socklen_t addrlen = sizeof(sin);
int fd;
if((fd =open(filename,O_WRONLY|O_CREAT|O_TRUNC,0664))== -1)
{
ERR_MSG("open error");
return -1;
}
int res =0;
while(1)
{
//接收数据recvfrom,接收地址信息
if(( res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,&addrlen))<0)
{
ERR_MSG("recvfrom error");
return -1;
}
printf("%s\n",buf+4);
//判断数据是否小于512字节,若小于则下载完成
if(res<516)
{
write(fd,buf+4,res-4);
break;
}
else if(res == 516)
{
write(fd,buf+4,512);
}
//组ACK包
unsigned short *ptr1 = (unsigned short *)buf;
*ptr1 = htons(4);
//发送ACK sendto
if(sendto(cfd,buf,4,0,(struct sockaddr *)&sin,sizeof(sin))<0)
{
ERR_MSG(sendto error);
return -1;
}
}
printf("下载完成\n");
}
int do_upload(int cfd,struct sockaddr_in sin)
{
char buf[516] = "";
int res =0;
char filename[20] = "";
printf("请输入要上传的文件名>>>");
scanf("%s",filename);
while(getchar()!=10);
int fd;
if((fd = open(filename,O_RDONLY))==-1)
{
ERR_MSG("open error");
return -1;
}
//写请求
//操作码
unsigned short *ptr1 =(unsigned short *)buf;
*ptr1 = htons(2);
//文件名
char *ptr2 = buf +2;
strcpy(*ptr2,filename);
//模式
char ptr4 = ptr2+strlen(filename)+1;
strcpy(*ptr4,"octet");
int size =2+strlen(ptr2)+2+strlen(ptr4);
//发送上传请求 sendto
if(sendto(cfd,buf,size,0,(struct sockaddr *)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto success");
return -1;
}
printf("request success\n");
int res;
socklen_t addrlen = sizeof(sin);
int blockNum = 0;
while(1)
{
blockNum ++;
//接收数据recvfrom,接收地址信息
if((res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr *)&sin,&addrlen))<0)
{
ERR_MSG("recvfrom error");
return -1;
}
//组数据包
//操作码
unsigned short *ptr1 =(unsigned short *)buf;
*ptr1 =htons(3);
unsigned short *ptr2 =(unsigned short *)(buf+2);
*ptr2 = blockNum;
}
}