6月10作业

UDP上传

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#define ERR_MSG(msg)                                                       \
    do                                                                     \
    {                                                                      \
        fprintf(stderr, "line:%d: %s %s\n", __LINE__, __FILE__, __func__); \
        perror(msg);                                                       \
    } while (0)

typedef struct
{
    int Server_Port;
    int Client_Port;
    char *Server_IP;
    char *Client_IP;
} UDPoptionTyp;

typedef struct
{
    uint16_t opcode;
    uint16_t block_num;
    char Buf_data[512];

} Data_UnpackDataTyp;

typedef struct
{
    FILE *fp;
    char Buf[516];
    char *name;
    char *mode;
    char WrR;
} FtpDldDatTyp;

struct sockaddr_in cin;// 创建报式套接字

Data_UnpackDataTyp Data_Unpack(const char *addr)
{
    Data_UnpackDataTyp Data;
    short *ptr = (short *)addr;
    Data.opcode = ntohs(*ptr);
    ptr++;
    Data.block_num = ntohs(*ptr);
    ptr++;
    char *ptr1 = (char *)ptr;
    for (int i = 0; i < 512; i++)
    {
        Data.Buf_data[i] = *ptr1;
        ptr1++;
    }
    return Data;
}

void UDP_Transm(int *sfd, UDPoptionTyp *arg)
{
    UDPoptionTyp Option_Data = *arg;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(Option_Data.Server_Port);
    cin.sin_addr.s_addr = inet_addr(Option_Data.Server_IP);
    socklen_t addrlen = sizeof(cin);

    *sfd = socket(AF_INET, SOCK_DGRAM, 0);
    //return cin;
}

char FtpDown_Init(int sfd, FtpDldDatTyp *Down_Name, ssize_t *Num_Data)
{
    socklen_t addrlen = sizeof(cin);
    int Size_World = sprintf(Down_Name->Buf, "%c%c%s%c%s%c", 0, Down_Name->WrR, Down_Name->name, 0, Down_Name->mode, 0); // 下载请求内容封包
    if (sendto(sfd, Down_Name->Buf, Size_World, 0, (struct sockaddr *)&cin, sizeof(cin)) < 0)                         // 发送下载请求
    {
        ERR_MSG("send");
        return -1;
    }
    if ((*Num_Data = recvfrom(sfd, Down_Name->Buf, sizeof(Down_Name->Buf), 0, (struct sockaddr *)&cin, &addrlen)) < 0)
    {
        ERR_MSG("recvfrom");
        return -1;
    }
    printf("客户端信息:[IP:PORT][%s : %d]\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));
    printf("数据包大小:%ld\n", *Num_Data);
    Data_UnpackDataTyp Data = Data_Unpack(Down_Name->Buf);
    if (Data.opcode == 3)
    {
        if ((Down_Name->fp= fopen(Down_Name->name, "w")) == NULL)
        {
            perror("create file");
            return -1;
        }
        fwrite(Data.Buf_data, 1, (*Num_Data) - 4,Down_Name->fp);
        printf("opcode :%d  num:%d \n", Data.opcode, Data.block_num);
    }
    else if (Data.opcode == 5)
    {
        printf("下载接收错误码\n");
        return -1;
    }
    
    return 0;
}

ssize_t Ftp_DownWrite(const int sfd, FtpDldDatTyp *Down_Name, ssize_t *Size_num)
{
    int Size_World;
    ssize_t Num_Data;
    socklen_t addrlen = sizeof(cin);
    Data_UnpackDataTyp Data = Data_Unpack(Down_Name->Buf);
    if (Data.opcode == 5)
    {
        ERR_MSG("download");   
        return -1;
    }
    else if (Data.opcode == 3)
    {     
        Size_World = sprintf(Down_Name->Buf, "%c%c%c%c", 0, 4, Down_Name->Buf[2], Down_Name->Buf[3]);
        if (sendto(sfd, Down_Name->Buf, Size_World, 0, (struct sockaddr *)&cin, sizeof(cin)) < 0)                         // 发送下载请求
        {   
            ERR_MSG("send");
            return -1;
        }
        if ((Num_Data = recvfrom(sfd, Down_Name->Buf, sizeof(Down_Name->Buf), 0, (struct sockaddr *)&cin, &addrlen)) < 0)
        {
            ERR_MSG("recvfrom");
            return -1;
        }
        Data = Data_Unpack(Down_Name->Buf);
        fwrite(Data.Buf_data, 1, Num_Data - 4, Down_Name->fp);
        Size_num += (Num_Data - 4);

        if (Data.opcode == 5)
        {
            ERR_MSG("download");
            printf("%s\n",Down_Name->Buf+4);
            return -1;
        }
    }
    bzero(Data.Buf_data, sizeof(Data.Buf_data));
    return Num_Data;
}

int main()
{
    UDPoptionTyp Option_Data = {69, 6666, "192.168.2.58", "192.168.2.184"};
    FtpDldDatTyp *Down_Name=(FtpDldDatTyp *)malloc(sizeof(FtpDldDatTyp));
//    FtpDldDatTyp Down_Name;
    ssize_t Size_num=0;
    ssize_t Num_Data;
    Down_Name->name = "renyu.png";
    Down_Name->mode = "octet";
    Down_Name->WrR = 1;
    int sfd;
    UDP_Transm(&sfd, &Option_Data);
    if (sfd < 0)
    {
        ERR_MSG("socket");
        return -1;
    }printf("create socket success sfd=%d \n", sfd);
    
    if (FtpDown_Init(sfd, Down_Name,&Num_Data) < 0)
    {
        ERR_MSG("Ftp_Init");
        return -1;
    }printf("Init success \n");

    Size_num+=Num_Data;

    while (Num_Data == sizeof(Down_Name->Buf))
    {
        Num_Data = Ftp_DownWrite(sfd, Down_Name,&Size_num);
        Size_num+=Num_Data;
    }
    printf("send success!\n");
    printf("Size:%ld\n", Size_num);
    fclose(Down_Name->fp); // 关闭文件
    close(sfd); // 关闭套接字
    free(Down_Name);
    Down_Name=NULL;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值