2024.03.01作业

1. 基于UDP的TFTP文件传输

#include "test.h"

#define SER_IP "192.168.1.104"
#define SER_PORT 69
#define IP "192.168.191.128"
#define PORT 9999

enum mode
{
    TFTP_READ = 1,
    TFTP_WRITE = 2,
    TFTP_DATA = 3,
    TFTP_ACK = 4,
    TFTP_ERR = 5
};

void get_filename(char* filename, int size)
{
    bzero(filename, size);

    printf("请输入文件名:");
    fgets(filename, size, stdin);
    filename[strlen(filename) - 1] = 0;
}

void rw_request(char* pack, int pack_size, char* filename, int mode, int* packlen)
{
    bzero(pack, pack_size); 

    short* p1 = (short*)pack;
    *p1 = htons(mode);

    char* p2 = (char*)(p1 + 1);
    strcpy(p2, filename);

    char* p4 = p2 + strlen(p2) + 1;
    strcpy(p4, "octet");

    *packlen = 4 + strlen(p2) + strlen(p4);
}

void pack_data(char* pack, int num, char* rbuf, int len, int* packlen)
{
    bzero(pack, sizeof(pack)); 

    short* p1 = (short*)pack;
    *p1 = htons(TFTP_DATA);

    short* p2 = p1 + 1;
    *p2 = htons(num);

    char* p4 = (char*)(p2 + 1);
    for (int i = 0; i < len; i++)
    {
        *(p4 + i) = rbuf[i];
    }

    *packlen = 4 + len;
}

void pack_ack(char* ack, int num)
{
    bzero(ack, 4);

    short* a = (short*)ack;
    *a = htons(TFTP_ACK);
    *(a + 1) = htons(num);
}

void pack_errmsg(char* pack, char* msg, int* packlen)
{
    bzero(pack, sizeof(pack));

    short* p = (short*)pack;
    *p = htons(TFTP_ERR);
    *(p + 1) = htons(0);

    char* errmsg = (char*)(p + 2);
    strcpy(errmsg, msg);

    *packlen = 4 + strlen(errmsg);
}

void client_recv(int sfd, struct sockaddr_in* sin, socklen_t* socklen)
{
    char filename[128];
    get_filename(filename, sizeof(filename));

    char pack[516] = "";
    int packlen = 0;
    rw_request(pack, sizeof(pack), filename, TFTP_READ, &packlen);
    
    sendto(sfd, pack, packlen, 0, (struct sockaddr*)sin, *socklen);

    int fd = -1;
    if ((fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0664)) == -1)
    {
        perror("create file error");
        return;
    }

    char wbuf[512] = "";
    int block_num = 0;
    while (1)
    {
        bzero(pack, sizeof(pack));
        packlen = recvfrom(sfd, pack, sizeof(pack), 0, (struct sockaddr*)sin, socklen);
        short* p = (short*)pack;
        short code = ntohs(*p);
        short num = ntohs(*(p + 1));

        if (3 == code && num == ++block_num)
        {
            write(fd, pack + 4, packlen - 4);

            char ack[4];
            pack_ack(ack, block_num);
            sendto(sfd, ack, 4, 0, (struct sockaddr*)sin, *socklen);
            
            if (packlen < 512)
            {
                printf("下载完成\n");
                close(fd);
                break;
            }
        }
    }
}

void client_send(int sfd, struct sockaddr_in* sin, socklen_t* socklen)
{
    char filename[128];
    get_filename(filename, sizeof(filename));

    char pack[516] = "";
    int packlen = 0;
    rw_request(pack, sizeof(pack), filename, TFTP_WRITE, &packlen);

    sendto(sfd, pack, packlen, 0, (struct sockaddr*)sin, *socklen);

    int fd = -1;
    if ((fd = open(filename, O_RDONLY)) == -1)
    {
        perror("open error");
        return;
    }

    char ack[4];
    char rbuf[512] = "";
    int len;
    while (1)
    {
        recvfrom(sfd, ack, 4, 0, (struct sockaddr*)sin, socklen);
        short* a = (short*)ack;
        short code = ntohs(*a);
        short num = ntohs(*(a + 1));

        if (4 == code && (len = read(fd, rbuf, sizeof(rbuf))) > 0)
        {
            pack_data(pack, num + 1, rbuf, len, &packlen);

            sendto(sfd, pack, packlen, 0, (struct sockaddr*)sin, *socklen);

            bzero(rbuf, sizeof(rbuf));

        }
        else
        {
            printf("上传成功\n");
            break;
        }
    }
}

int main(int argc, char const *argv[])
{
    int sfd = -1;
    sfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (-1 == sfd)
    {
        perror("socket error");
        return -1;
    }
    printf("sfd = %d\n", sfd);

    int reuse = 1;
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("端口号快速重用成功\n");

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);
    socklen_t socklen = sizeof(sin);

    printf("1.上传\n");
    printf("2.下载\n");
    printf("0.退出\n");
    printf("请输入:");
    int n;
    scanf("%d", &n);
    getchar();

    if (1 == n)
    {
        client_send(sfd, &sin, &socklen);
    }
    else if (2 == n)
    {
        client_recv(sfd, &sin, &socklen);
    }
    else
    {
        printf("输入错误\n");
    }
    
    close(sfd);

    return 0;
}

2. TCP机械臂测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/424611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

内存空间担保机制

什么是内存空间担保机制&#xff1f; 内存空间担保机制&#xff08;Memory Space Guarantee&#xff09;是垃圾回收&#xff08;Garbage Collection&#xff09;算法中的一种策略。它用于在进行垃圾回收过程&#xff08;如Minor GC或Full GC&#xff09;时&#xff0c;确保老年…

KubeSphere平台安装系列之三【Linux多节点部署KubeSphere】(3/3)

**《KubeSphere平台安装系列》** 【Kubernetes上安装KubeSphere&#xff08;亲测–实操完整版&#xff09;】&#xff08;1/3&#xff09; 【Linux单节点部署KubeSphere】&#xff08;2/3&#xff09; 【Linux多节点部署KubeSphere】&#xff08;3/3&#xff09; **《KubeS…

【IC前端虚拟项目】inst_buffer子模块DS与RTL编码

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 需要说明一下的是,在我所提供的文档体系里,并没有模块的DS文档哈,因为实际项目里我也不怎么写DS毕竟不是每个公司都和HISI一样对文档要求这么严格的。不过作为一个培训的虚拟项目,还是建议在时间充裕…

C++ //练习 10.22 重写统计长度小于等于6 的单词数量的程序,使用函数代替lambda。

C Primer&#xff08;第5版&#xff09; 练习 10.22 练习 10.22 重写统计长度小于等于6 的单词数量的程序&#xff0c;使用函数代替lambda。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /********************************…

RNA-Seq 笔记 [4]

***********************该笔记为初学者笔记&#xff0c;仅供个人参考谨慎搬运代码****************************** samtools 排序压缩和 featureCounts 生成基因计数表 SAM文件和BAM文件 1.SAM格式&#xff1a;是一种通用的比对格式&#xff0c;用来存储reads到参考序列的比…

二维数组详解(C语言)

一维数组详解链接&#xff1a;http://t.csdnimg.cn/PbzKF 前言看过一维数组&#xff0c;我们来看一下二维数组。 目录 目录 1. ⼆维数组的创建 1.1 ⼆维数组的概念 1.2 ⼆维数组的创建 2. ⼆维数组的初始化 2.1 不完全初始化 2.2 完全初始化 2.3 按照⾏初始化 2.4 初…

Mybatis Plus框架 基本语法

MybatisPlus 中文官网 依赖配置 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mav…

Verilog原语、Verilog保留关键字

Verilog基元 Vivado合成支持Verilog门级原语&#xff0c;下表所示除外。 Vivado合成不支持Verilog开关级原语&#xff0c;例如以下原语&#xff1a; cmos、nmos、pmos、rcmos、rnmos、rpmos rtran、rtranif0、rtranif1、tran&#xff0c; tranif0&#xff0c;tranif1 门级…

LeetCode102.二叉树的层序遍历

题目 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[9,20],[15,7]]输入&#xff1a;root [1] 输出&am…

Springboot+vue的高校教师教研信息填报系统(有报告)。Javaee项目,springboot vue前后端分离项目。

演示视频&#xff1a; Springbootvue的高校教师教研信息填报系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&am…

mongodb 图形界面工具 -- Studio 3T(下载、安装、连接mongodb数据库)

目录 mongodb 图形界面工具 -- Studio 3T下载安装第一次使用&#xff1a;注册添加一个连接&#xff08;连接 mongodb 数据库&#xff09;1、点击【添加新连接】&#xff0c;选择【手动配置我的连接设置】2、对 Server 设置连接数据3、连接的用户认证设置&#xff08;创建数据库…

区块链媒体:链游媒体宣发渠道9个方法分享-华媒舍

在当今的游戏市场中&#xff0c;要想让自己开发的游戏脱颖而出&#xff0c;宣传策略的选择也至关重要。链游媒体是一种有效的宣发渠道&#xff0c;通过它们可以向广大玩家推广游戏并提高知名度。下面介绍9个链游媒体宣发渠道&#xff0c;帮助你的游戏走向成功。 1. 游戏公众号 …

6U VPX全国产飞腾D2000/8核+复旦微FPGA信息处理主板

产品特性 产品功能 飞腾计算平台&#xff0c;国产化率100% VPX-MPU6503是一款基于飞腾D2000/8核信息处理主板&#xff0c;采用由飞腾D2000处理器飞腾X100桥片的高性能计算机模块&#xff0c;双通道16G贴装内存&#xff0c;板载128G 固态SSD&#xff1b;预留固态盘扩展接口&…

ABAP-CPI: Get CPI Monitoring Log (通过postman去获取CPI监控中心的日志)

参照文档: SAP Business Accelerator Hub Using Message Monitoring and Logging (sap.com) 进入到你的CPI监控中心: 获取到上面的 https://..hana.ondemand.com的地址,在它后面加上/api/v1 即https://....hana.ondemand.com/api/v1 然后就可以开始postman调用了,文章…

UE 打包窗口及鼠标状态设置

UE 打包窗口及鼠标状态设置 打包后鼠标不锁定 显示鼠标图标 打包后设置窗口模式 找到打包路径下的配置文件GameUserSettings&#xff0c;设置相关项目 FullscreenMode0表示全屏模式&#xff0c;1表示窗口全屏模式&#xff0c;2表示窗口模式

NIO核心三:Selector

一、基本概念 选择器提供一种选择执行已经就绪的任务的能力。selector选择器可以让单线程处理多个通道。如果程序打开了多个连接通道&#xff0c;每个连接的流量都比较低&#xff0c;可以使用Selector对通道进行管理。 二、如何创建选择器 1.创建Selector Selector select…

【three.js】Camera相机四大参数详解

先说一个概念,threejs中的相机其实就是一个视椎体,如下图: 两个绿色的面分别是近裁截面和远裁截面,在两个面之间,我们能看到网格模型,如果网格模型在两个面外,那么你是看不到的。 那么明白这一点,我们看代码说明。 这里拿PerspectiveCamera透视投影相机举例: // 引…

Git与GitHub:解锁版本控制的魔法盒子

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

Go-知识简短变量声明

Go-知识简短变量声明 1. 简短变量声明符2. 简短变量赋值可能会重新声明3. 简短变量赋值不能用于函数外部4. 简短变量赋值作用域问题5. 总结 githuio地址&#xff1a;https://a18792721831.github.io/ 1. 简短变量声明符 在Go语言中&#xff0c;可以使用关键字var或直接使用简短…

医疗行业数据分析,为医疗提质增效提供科学支持

信息化时代的到来&#xff0c;医疗行业数据分析已成为提升医疗服务质量和效率的重要手段。医院拥有大量的医疗数据&#xff0c;医疗数据中包含着很多宝贵的信息与规律&#xff0c;通过深入的数据分析&#xff0c;能够为决策者提供直观、深入的数据洞察&#xff0c;帮助医疗服务…