欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > day36——homework

day36——homework

2024/10/24 15:13:31 来源:https://blog.csdn.net/m0_69277585/article/details/141201525  浏览:    关键词:day36——homework

二、基于UDP的TFTP文件传输

1)tftp协议概述

简单文件传输协议,适用于在网络上进行文件传输的一套标准协议,使用UDP传输

特点:

是应用层协议

基于UDP协议实现

数据传输模式

octet:二进制模式(常用)

mail:已经不再支持

2)tftp下载模型

TFTP通信过程总结

  1. 服务器在69号端口等待客户端的请求
  2. 服务器若批准此请求,则使用 临时端口 与客户端进行通信。
  3. 每个数据包的编号都有变化(从1开始)
  4. 每个数据包都要得到ACK的确认,如果出现超时,则需要重新发送最后的数据包或ACK包
  5. 数据长度以512Byte传输的,小于512Byte的数据意味着数据传输结束。

3)tftp协议分析

差错码:

0 未定义,差错错误信息

1 File not found.

2 Access violation.

3 Disk full or allocation exceeded.

4 illegal TFTP operation.

5 Unknown transfer ID.

6 File already exists.

7 No such user.

8 Unsupported option(s) requested.

#include <myhead.h>
#define SER_PORT 69            //服务器端口号
#define SER_IP "192.168.0.115" //服务器ip地址
#define CLI_PORT 5555          //客户端端口号
#define CLI_IP "192.168.0.100" //客户端ip地址
#define BUF_SIZE 516           //缓冲区大小
#define TIMEOUT 3              //超时时间(秒)
void display()
{printf("请选择功能:\n");printf("1. 文件下载\n");printf("2. 文件上传\n");printf("3. 退出程序\n");
}
int main(int argc, const char *argv[])
{while (1){int k = 0;display();int choice;scanf("%d", &choice);char filename[100];if (choice == 1 || choice == 2){printf("请输入文件名: ");scanf("%s", filename);}int file = open(filename, O_RDWR | O_CREAT, 0664);if (file == -1){printf("无法打开文件 %s\n", filename);return 1;}switch (choice){case 1:{//1、创建用于通信的服务器套接字文件描述符int cfd = socket(AF_INET, SOCK_DGRAM, 0);if (cfd == -1){perror("socket error");return -1;}printf("cfd = %d\n", cfd); //3//2、向服务器发送下载请求char buf[BUF_SIZE];short *p1 = (short *)buf;*p1 = htons(1); //操作码char *p2 = buf + 2;strcpy(p2, filename); //文件名char *p4 = p2 + strlen(p2) + 1;strcpy(p4, "octet");                        //模式位int size = 2 + strlen(p2) + strlen(p4) + 2; //请求包的总长度//将请求包发送给服务器struct sockaddr_in sin;socklen_t sinlen = sizeof(sin);sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sinlen);while (1){ssize_t str_len = recvfrom(cfd, buf, BUF_SIZE, 0, (struct sockaddr *)&sin, &sinlen);if (ntohs(*p1) == 3){write(file, buf + 4, str_len - 4);*p1 = htons(4);sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sinlen);if (str_len < BUF_SIZE - 4){break;}}}//发送分手请求*p1 = htons(5);sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sinlen);close(cfd);bzero(buf, BUF_SIZE);break;}case 2:{// 1、创建用于通信的服务器套接字文件描述符int cfd = socket(AF_INET, SOCK_DGRAM, 0);if (cfd == -1){perror("socket error");return -1;}printf("cfd = %d\n", cfd); //3// 2、向服务器发送上传请求char buf[BUF_SIZE];short *p1 = (short *)buf;*p1 = htons(2); //操作码,表示上传char *p2 = buf + 2;strcpy(p2, filename); //文件名char *p4 = p2 + strlen(p2) + 1;strcpy(p4, "octet");                        //模式位int size = 2 + strlen(p2) + strlen(p4) + 2; //请求包的总长度// 将请求包发送给服务器struct sockaddr_in sin;socklen_t sinlen = sizeof(sin);sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sinlen);short *ack = (short *)(buf + 2);int n = 1;while (1){ssize_t str_len = recvfrom(cfd, buf, BUF_SIZE, 0, (struct sockaddr *)&sin, &sinlen);if (ntohs(*p1) == 4){int res = read(file, buf + 4, BUF_SIZE - 4);*p1 = htons(3);*ack = htons(n);n++;sendto(cfd, buf, BUF_SIZE, 0, (struct sockaddr *)&sin, sinlen);if (res < BUF_SIZE - 4){break;}}}//发送分手请求*p1 = htons(5);sendto(cfd, buf, size, 0, (struct sockaddr *)&sin, sinlen);close(cfd);bzero(buf, BUF_SIZE);break;}case 3:{k = 1;break;}}printf("k=%d\n", k);if (k == 1){break;}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com