#include<th.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
#define PORT 69 //端口号,范围1024~49151
#define IP "192.168.115.90" //本机IP
int do_download(int cfd,struct sockaddr_in sin)
{
char filename[20] = "";
printf("请输入要下载的文件名: ");
scanf("%s",filename);
while(getchar() != 10);
//组下载请求包
char buf[516] = "";
unsigned short * ptr1 = (unsigned short *)buf;
*ptr1 = htons(1); //组操作码
char * ptr2 = buf + 2;
strcpy(ptr2,filename); //组文件名
char * ptr4 = ptr2 + strlen(filename) + 1;
strcpy(ptr4,"octet"); //组模式
int size = 2 + strlen(ptr2) + 1 + strlen(ptr4) + 1;
//发送下载请求 sendto
if(sendto(cfd,buf,size,0,(struct sockaddr *)&sin,sizeof(sin)) < 0)
{
ERR_MSG("sendto error");
return -1;
}
printf("sendto success\n");
struct sockaddr_in cin; //存储对方的地址信息
socklen_t addrlen = sizeof(cin);
while(1)
{
//接收数据 recvfrom,接收地址信息
if(recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr * )&cin,&addrlen) < 0)
{
ERR_MSG("recvfrom error");
return -1;
}
printf("recvfrom success\n");
//组ACK包
char buf1[4] = "";
unsigned short * p1 = (unsigned short * )buf1;
*p1 = htons(4); //组操作码
char code[2];
printf("请输入块编号: ");
scanf("%s",code);
strcpy(p1 + 1,code);
//发送ACK sendto
if(sendto(cfd,buf1,sizeof(buf1),0,(struct sockaddr *)&sin,sizeof(sin)) < 0)
{
ERR_MSG("sendto ACK error");
return -1;
}
printf("sendto ACK success\n");
//判断数据是否小于512个字节,若小于则下载完成
if(addrlen < 512)
{
break;
}
}
return 0;
}
int do_upload()
{
return 0;
}
int main(int argc, const char *argv[])
{
//创建报式套接字 socket
int cfd = socket(AF_INET,SOCK_DGRAM,0);
if(cfd < 0)
{
ERR_MSG("socket error");
return -1;
}
printf("socket create success cfd = %d\n",cfd);
//填充服务器的地址信息结构体,给bind函数使用
//真实的地址信息结构体根据地址族指定,AF_INET man 7 IP
struct sockaddr_in sin;
sin.sin_family = AF_INET; //必须填AF_INET
sin.sin_port = htons(PORT); //端口号的网络字节序,1024~49151
sin.sin_addr.s_addr = inet_addr(IP); //本机IP
char choose = 0;
while(1)
{
system("clear");
printf("******************************\n");
printf("**********1. 下载************\n");
printf("**********2. 上传************\n");
printf("**********3. 退出************\n");
printf("******************************\n");
printf("请输入>>> ");
scanf("%c",&choose);
while(getchar() != 10);
switch(choose)
{
case '1':
{
do_download(cfd,sin);
break;
}
case '2':
{
do_upload();
break;
}
case '3':
{
goto END;
break;
}
default:
{
printf("输入错误,请重新输入\n");
break;
}
printf("输入任意字符清屏>>> ");
while(getchar() != 10);
}
}
END:
//关闭套接字
close(cfd);
return 0;
}
DAY37
最新推荐文章于 2024-09-24 10:23:52 发布