tftp协议概述
简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输
特点:
是应用层协议
基于UDP协议实现
数据传输模式
octet:二进制模式(常用)
mail:已经不再支持
代码:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#define MSG(msg) do{\
printf("__%d__",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
int pp = socket(AF_INET,SOCK_DGRAM,0);
struct sockaddr_in dd;
dd.sin_family = AF_INET;
dd.sin_port = htons(69);
dd.sin_addr.s_addr = inet_addr(argv[1]);
// char buf[128] = "";
printf("请输入要下载的文件:");
char filename[20];
scanf("%s",filename);
//读写请求
//操作码
char buf[128] = "";
short int *pa = (short int *)buf;
*pa = htons(1);
//文件名
char*pb = buf+2;
strcpy(pb,filename);
//0
char*pc = pb+strlen(pb);
*pc = 0;
//模式
char *pd = pc+1;
strcpy(pd,"octet");
pd[strlen(pd)] = 0;
//连接服务器
int size ;
size = 2+strlen(pb)+1+strlen(pd);
sendto(pp,buf,size,0,(struct sockaddr*)&dd,sizeof(dd));
//数据包
char brr[600];
struct sockaddr_in cin;
socklen_t addlen = sizeof(cin);
//ACK
char crr[4]="";
*(short int*)crr = htons(4);
//块编号
short int num=0;
//下载到的文件
int file = open("./111",O_WRONLY|O_CREAT|O_TRUNC,0664);
int res;
while(1)
{
//接收服务器发送数据包
bzero(brr,sizeof(brr));
res = recvfrom(pp,brr,sizeof(brr),0,(struct sockaddr*)&cin,&addlen);
if(res<0)
{
MSG("recvfrom");
return -1;
}
//判断错误码
/*
short int *a1 = (short int*)brr;
short int *a2 = (short int*)(brr+2);
if(*a1==5)
{
char*a3 = brr+4;
printf("%s\n",a3);
}
*/
write(file,brr+4,res-4);
if(res<516)
break;
//赋值ACK
short int* p1 = (short int*)(brr+2);
short int *p2 = (short int *)crr;
p2++;
*p2 = *p1;
//发送ACK
sendto(pp,crr,sizeof(crr),0,(struct sockaddr*)&cin,addlen);
}
close(pp);
close(file);
return 0;
}
结果: