思维导图
tftp下载
#include<myhead.h>
#define PORT 69
#define IP "192.168.114.122"
int do_download(int client_socket, struct sockaddr_in server_addr);
int do_upload(int client_socket, struct sockaddr_in server_addr);
int main(int argc, const char *argv[])
{
//新建套接字文件
int client_socket = socket(AF_INET, SOCK_DGRAM, 0);
if(client_socket == -1){
ERR_MSG("socket");
return -1;
}
printf("socket success\n");
//定义要发送的地址信息结构体
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.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); //循环吸收垃圾字符
switch(choose)
{
case '1':
do_download(client_socket, server_addr);
break;
case '2':
do_upload(client_socket, server_addr);
break;
case '3':
goto END;
break;
default:
printf("输入错误,请重新输入\n");
break;
}
printf("请输入任意字符清屏>>>");
while(getchar() != 10);
}
#if 0
char msg[128] = "hello world";/*{{{*//*{{{*/
char buf[128] = "";
ssize_t ret;
while(1){
//发送数据
sleep(2);
sendto(client_socket, msg, sizeof(msg), 0,\
(const struct sockaddr *)&server_addr,\
sizeof(server_addr));
printf("已将%s发送给[%s:%d] client_socket = %d\n",msg,\
inet_ntoa(server_addr.sin_addr),\
ntohs(server_addr.sin_port), client_socket);
//接收数据
//清空字符串
bzero(buf, sizeof(buf));
socklen_t server_addr_len = sizeof(server_addr);
ret = recv(client_socket, buf, sizeof(buf), 0);
if(ret == -1){
ERR_MSG("recvfrom");
break;
}
printf("已将%s从[%s:%d]接收 client_socket = %d\n",buf,\
inet_ntoa(server_addr.sin_addr),\
ntohs(server_addr.sin_port), client_socket);
putchar(10);
}/*}}}*//*}}}*/
#endif
END:
//关闭套接字文件
if(close(client_socket) == -1){
ERR_MSG("close");
return -1;
}
return 0;
}
int do_download(int client_socket, struct sockaddr_in server_addr)
{
char ack[4] = "";
char buf[516] = "";
char filename[20] = "";
int ret;
FILE *file = fopen("./received_image.png", "w");
if(file == NULL)
{
ERR_MSG("fopen");
return -1;
}
printf("请输入要下载的文件名\n");
scanf("%s",filename);
while(getchar() != 10);
//组下载请求包
unsigned short* ptr1 = (unsigned short*)buf;
*ptr1 = htons(1);
char *ptr2 = buf+2;
strcpy(ptr2, filename);
char *ptr3 = ptr2+strlen(filename)+1;
strcpy(ptr3, "octet");
int size = 2+strlen(ptr2)+strlen(ptr3)+2;
//发送下载请求 sendto
if(sendto(client_socket, buf, size, 0,\
(struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
{
ERR_MSG("buf sendto");
return -1;
}
printf("sendto download request success\n");
while(1)
{
//接收数据 recvfrom, 接收地址信息
bzero(buf, sizeof(buf));
socklen_t server_addr_len = sizeof(server_addr);
ret = recvfrom(client_socket, buf, sizeof(buf), 0,\
(struct sockaddr*)&server_addr, &server_addr_len);
printf("接收了%d个字符\n",ret);
if(ret == -1)
{
ERR_MSG("recvfrom");
break;
}
unsigned short opcode = ntohs(*(unsigned short*)buf);
if(opcode == 3)
{
fwrite(buf+4, 1, ret-4, file);
}else if(opcode == 5)
{
ERR_MSG("opcode");
break;
}
//组ack包
unsigned short *ptr4 = (unsigned short*)ack;
*ptr4 = htons(4);
unsigned short *ptr5 = ptr4+1;
*ptr5 = *(unsigned short*)(buf+2);
//发送ack sendto
if(sendto(client_socket, ack, 4, 0,\
(struct sockaddr*)&server_addr, sizeof(server_addr)) == -1)
{
ERR_MSG("ack sendto");
return -1;
}
printf("ack sendto success\n");
//判断数据是否小于512字节,若小于则下载完成
if(ret < 516)
{
printf("download success\n");
break;
}
}
fclose(file);
}