TFTP协议的下载功能代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
//打印错误新的宏函数
#define ERR_MSG(msg) do{\
fprintf(stderr, " __%d__ ", __LINE__);\
perror(msg);\
}while(0)
#define IP "192.168.31.97" //本机IP,用ifconfig查看
#define PORT 69 //1024~49151
void menu()
{
printf("******************\n");
printf("*****1.下载*******\n");
printf("*****2.上传*******\n");
printf("*****3.退出*******\n");
printf("******************\n");
}
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd < 0)
{
ERR_MSG("socket");
return -1;
}
printf("create socket success\n");
//填充地址信息结构体,真实的地址信息结构体与协议族相关
//AF_INET,所以详情请看man 7 ip
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT); //网络字节序的端口号
sin.sin_addr.s_addr = inet_addr(IP); //网络字节序的IP地址
struct sockaddr_in cin; //存储接收到的数据包来自哪里
socklen_t addrlen = sizeof(cin);
char buf[600] = "";
int input;
do{
menu();
scanf("%d",&input);
switch(input)
{
case 1:
//发送请求
bzero(buf,sizeof(buf));
int size=0;
short int n=1;
char* ptr=buf;
short int* pa=(short int*)ptr;
*pa=htons(1);
char* pb=ptr+2;
strcpy(pb,"5.png");
char* pc=pb+strlen(pb);
char* pd=pc+1;
strcpy(pd,"octet");
size=2+strlen(pb)+1+strlen("octet")+1;
if(sendto(sfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) < 0)
{
ERR_MSG("sendto");
return -1;
}
int fp =open("./1.png",O_WRONLY|O_CREAT,0664);
if(fp<0)
{
ERR_MSG("open");
return -1;
}
while(1)
{
//接收数据包
bzero(buf,sizeof(buf));
int res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cin,&addrlen);
if(res<0)
{
ERR_MSG("recvfrom");
return -1;
}
if(ntohs(*(short int*)buf)!=3)
{
printf("接收错误\n");
}
if(ntohs(*(short int*)(buf+2))!=n)
{
continue;
}
//写入指定文件
if(write(fp,buf+4,res-4)<0)
{
ERR_MSG("write");
return -1;
}
if(res<512)
{
printf("下载完毕\n");
break;
}
//发送ack
*(short int*)buf=htons(4);
*(short int*)(buf+2)=htons(n);
if(sendto(sfd,buf,4,0,(struct sockaddr*)&cin,sizeof(cin))<0)
{
ERR_MSG("sendto");
return -1;
}
n++;
}
close(fp);
close(sfd);
break;
case 2:
break;
case 3:
exit(0);
default :
printf("输入错误\n");
}
}while(input);
close(sfd);
return 0;
}