• day36:网编day3,TCP、UDP模型


    下载:

    1. #include <myhead.h>
    2. #define ERR(s) do\
    3. {\
    4. fprintf(stderr,"__%d__",__LINE__);\
    5. perror(s);\
    6. }while(0)
    7. #define PORT 69
    8. #define IP "192.168.115.184"
    9. int do_download(int cfd,struct sockaddr_in sin);
    10. //int do_upload();
    11. int main(int argc, const char *argv[])
    12. {
    13. //创建报式套接字socket
    14. int cfd;
    15. if((cfd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
    16. {
    17. ERR("socket");
    18. return -1;
    19. }
    20. printf("socket success\n");
    21. struct sockaddr_in sin;
    22. sin.sin_family = AF_INET;
    23. sin.sin_port = htons(PORT);
    24. sin.sin_addr.s_addr = inet_addr(IP);
    25. char choose = 0;
    26. while(1)
    27. {
    28. system("clear");
    29. printf("--------------------------------\n");
    30. printf("-------------1下载--------------\n");
    31. printf("-------------2上传--------------\n");
    32. printf("-------------3退出--------------\n");
    33. printf("--------------------------------\n");
    34. printf("请输入>>>");
    35. scanf("%c",&choose);
    36. while(getchar()!=10); //吸收垃圾字符
    37. switch(choose)
    38. {
    39. case '1':
    40. do_download(cfd,sin);
    41. break;
    42. case '2':
    43. //do_upload();
    44. break;
    45. case '3':
    46. goto END;
    47. break;
    48. default :
    49. printf("输入错误,请重新输入\n");
    50. }
    51. printf("请输入任意字符清屏\n");
    52. while(getchar()!=10);
    53. }
    54. END:
    55. //关闭套接字
    56. close(cfd);
    57. return 0;
    58. }
    59. int do_download(int cfd,struct sockaddr_in sin)
    60. {
    61. /*
    62. //组下载请求包
    63. char buf[516] = "";
    64. char f_n[20] = "";
    65. //操作码
    66. unsigned short *ptr1 = (unsigned short*)buf;
    67. *ptr1 = htons(1); //组操作码
    68. //文件名
    69. char *ptr2 = (char *)(ptr1+1);
    70. strcpy(ptr2,f_n);
    71. //模式
    72. char *ptr3 = ptr2 + strlen(f_n) + 1;
    73. strcpy(ptr3,"octet");
    74. int size = 2+strlen(ptr2)+1+strlen(ptr3)+1;
    75. */
    76. char buf[516] = "";
    77. char f_n[20] = "";
    78. int num=1;
    79. printf("请输入文件名>>> ");
    80. //终端输入要下载的文件名
    81. fgets(f_n,sizeof(f_n),stdin);
    82. f_n[strlen(f_n)-1] = '\0';
    83. int fd;
    84. if((fd = open(f_n,O_WRONLY|O_CREAT|O_TRUNC,0664)) == -1)
    85. {
    86. ERR("open");
    87. return -1;
    88. }
    89. //用sprintf拼接
    90. int size = sprintf(buf,"%c%c%s%c%s%c",0,1,f_n,0,"octet",0);
    91. //发送下载请求sendto
    92. if(sendto(cfd,buf,size,0,(struct sockaddr*)&sin,sizeof(sin)) < 0 )
    93. {
    94. ERR("sendto askpackage");
    95. return -1;
    96. }
    97. printf("sendto askpackage success\n");
    98. ssize_t len = 0;
    99. struct sockaddr_in addrin;
    100. socklen_t addrlen=sizeof(addrin);
    101. while(1)
    102. {
    103. //清空buf
    104. bzero(buf,sizeof(buf));
    105. //接收数据recvfrom,接收地址信息
    106. if((len = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&addrin,&addrlen)) < 0)
    107. {
    108. ERR("recvfrom datapackage");
    109. return -1;
    110. }
    111. unsigned short ptr2=ntohs(*(unsigned short*)(buf+2));
    112. printf("%hu\n",ptr2);
    113. //当操作码为5
    114. if(5 == buf[1])
    115. {
    116. fprintf(stderr, "错误码:%d,错误信息:%s\n", ntohs(*(unsigned short*)(buf+2)), buf+4);
    117. break;
    118. }
    119. //当操作码为3,并且块编号正确时
    120. else if(3 == buf[1] && num == ptr2)
    121. {
    122. printf("%d\n",fd);
    123. //跳过前四个字节,写入文件
    124. if(write(fd,buf+4,len-4)<0)
    125. {
    126. ERR("write");
    127. return -1;
    128. }
    129. //组ACK包
    130. buf[1] = 4;
    131. //发送ACK包,sendto
    132. if(sendto(cfd,buf,4,0,(struct sockaddr*)&addrin,addrlen) < 0)
    133. {
    134. ERR("sendto ACKpackage");
    135. return -1;
    136. }
    137. num++;
    138. //判断数据是否小于512个字节,若小于则下载完成
    139. if(len < 516)
    140. {
    141. printf("download success\n");
    142. break;
    143. }
    144. }
    145. }
    146. close(fd);
    147. return 0;
    148. }

    思维导图有道云笔记

  • 相关阅读:
    Docker笔记1
    一文详解:Open SSL
    Insert or Merge
    【比特熊故事汇2.0】|即使每天都是新的探险,他也会快乐Say Hi
    【论文汇总】2D目标检测文章汇总,持续更新
    《Linux从练气到飞升》No.31 多线程编程实践与线程安全技术
    [附源码]Python计算机毕业设计Django防疫物资捐赠
    【Python基础】对Python的深入认识以及各种情况的报错汇总
    Vue/React实现路由鉴权/导航守卫/路由拦截(react-router v6)
    Java之spring新手教程(包教包会)
  • 原文地址:https://blog.csdn.net/wxmchong/article/details/132571842