2023/12/19 work

发布时间:2023年12月19日

1.?基于UDP的TFTP文件传输

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <myhead.h>

//实现下载功能
int do_download(int cfd, struct sockaddr_in sin)
{
    //定义变量存储下载请求包
    char buf[516] = "";
    //定义变量存储文件名
    char fileName[40] = "";

    printf("请输入文件名:");
    scanf("%s", fileName);
    getchar();

    //组装请求包
    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 = 4 + strlen(p2) + strlen(p4);      //要发送数据的大小
    	

    //向服务器发送下载请求
    if(sendto(cfd, buf, size, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("sendto error");
        return -1;
    }

    printf("请求成功\n");

	//循环接收回复服务器发来的消息
	//写文件
	int fd = -1;
	//以写的形式打开文件
	if((fd = open(fileName, O_WRONLY|O_CREAT|O_TRUNC, 0664)) == -1)
	{
		perror("open error");
		return -1;
	}

	socklen_t len = sizeof(sin);
	char *p5 = buf+4;

	while(1){
		bzero(buf,sizeof(buf));
		//接收服务器发送的请求
		int res = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&sin,&len);
		if(res == -1){
			perror("recvfrom error");
			return -1;
		}
		//printf("buf %s\n",buf);
		int data = buf[1];
		if(data == 3){ //发数据发送成功
			//写文件从5位开始
			if(res < 516){
				write(fd,p5,res-4);
				break;
			}else{
				write(fd,p5,512);
			}
			//发送ack
			buf[1] = 4;
			if(sendto(cfd, buf, 4, 0, (struct sockaddr*)&sin, sizeof(sin)) == -1)
			{
				perror("sendto error");
				return -1;
			}
		}

		if(data == 5){
			printf("error %s\n",p5);
			return -1;
		}
	}

	printf("下载完成\n");
	close(fd);


}

int main(int argc, const char *argv[])
{
    if(argc != 2)
    {
        printf("input error\n");
        printf("usage:./a.out ip\n");
        return -1;
    }

    //1、创建套接字
    int cfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(cfd == -1)
    {
        perror("socket error");
        return -1;
    }

    //2、填充服务器地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(69);
    sin.sin_addr.s_addr = inet_addr(argv[1]);

    int mune = -1;
    while(1)
    {
        system("clear");                     //清屏
        printf("\t\t======1、下载=======\n");
        printf("\t\t======2、上传=======\n");
        printf("\t\t======0、退出=======\n");

        printf("请输入功能:");
        scanf("%d", &mune);
        getchar();

        //多分支选择
        switch(mune)
        {
        case 1:
            {
                do_download(cfd, sin);
            }
            break;

        case 2:
            {
                //do_upload();
            }
            break;
        case 0:
            goto POS;
        default:printf("输入功能有误,请重新输入\n");
        }

        //阻塞
        printf("输入任意键,按回车清空:");
        while(getchar() != '\n');
    }

POS:
    //关闭套接字
    close(cfd);
    return 0;
}

文章来源:https://blog.csdn.net/qinww2009/article/details/135094302
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。