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);
}
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));
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;
}