TCP/IP和网络方案拟订 2021-2022-1

      最后更新:2021-11-22 20:58:04 手机定位技术交流文章

      一、任务详情

      自学材料,第13章和提交研究说明(10分)

      总结了知识要点,并突出强调了最有效益的知识要点(3点)。

      问题和解决办法的两点

      练习材料和截图以及代码链接(3点)

      ..(知识结构化、知识完整性等,提交标记纸,使用Opneler系统等)(两点)

      二、知识点总结

      本章第一部分涉及TCP/IP协议及其应用,涉及TCP/IP堆叠、IP地址、主机名、DNS、IP数据集和路由器;后半部分提供UDP和TCP协议、端口号以及TCP/IP网络的数据流;讨论服务器-客户计算模型和套件界面;通过使用UDP和TCP软件包的例子显示网络编程。
      本章第二节涵盖网络和地理信息中心编程,包括对HTTP编程模式、网页和浏览器的解释,以及如何设置Linux HTTPD服务器处理用户网页、PHP和CGI编程,对客户和服务器终端动态网页的解释,以及展示如何利用HP和CGI建立服务器终端动态网页。

      一. TCP/IP协议协议

      TCP/IP (Comer 1988; 2001; RFC 1180 1991)是互联网的基础。 TCP 代表传输控制协议。 IP 代表互联网协议。 现在有两种形式的IP, IPv4 和 IPv6.IPv4 使用32个地址, IPv6 使用128个地址。 本节介绍IPv4, IPv4仍然是最广泛使用的IP版本。 TCP/IP 的结构分为几层, 通常称为 TCP/IP 堆叠。

      程序与主机层之间或以上的数据传输只是合乎逻辑的。真正的数据传输发生在互联网(IP)和链层上,后者将数据包分割成数据框,供物理网络之间传输。下图描述了TCP/IP网络中的数据流路径。

      二. IP 主机和IP地址

      IP 地址分为两个部分, 网络ID 字段和 HostID 字段。 分解后, IP 地址被分类为 A- E 。 例如, B 类中的IP 地址被分为16位网络ID, 其中前两位为 10, 后一位是 16 位 HostID 字段。 发送到 IP 地址的软件包先被发送到与同一网络WorkingID 相同的路由器。 路由器将通过 HostID 将软件包转发给网络中的特定主机 。 每个主机都有一个本地主机名, 本地主机, 以及默认的 IP 地址 。 本地主机链层是一个返回虚拟设备, 将每个数据包返回同一本地主机 。 此功能允许我们在同一计算机上运行 TCP/ IP 应用程序, 而不实际连接互联网 。

      3.IP协议

      IP 协议用于在 IP 主机之间发送/接收数据包 。 IP 主机只需将软件包传送给接收者, 但它不能确保软件包将传送到其目的地或按顺序发送。 这意味着 IP 不是一个可靠的协议。 如果需要可靠性, 则必须在 IP 层上方建立可靠性 。

      4.UDP/TCP

      UDP(用户数据报告协议)(RFC768,1980年;Comer 1988年)是一个关于IP的协议,用于传输和接收数据报告。 和IP一样,UDP并不保证可靠性,而是快速有效的,可以在可靠性并不关键的情况下使用。

      TCP(传输控制协议)是用于传输/接收数据流的以连接为导向的协议。 TCP也可能在 IP 上运行,但它提供一致的数据传输。 UDP通常用于发送邮件,但TCP被用于发送数据流。

      5.端口编号

      应用程序 = (主机IP地址、协议和端口)
      协议是 TCP 或 UDP, 端口号是分配给程序的唯一未签名的短整数 。 要使用 UDP 或 TCP, 应用程序( process) 必须首先选择或获得端口号 。 保留了第一个 1024 端口号 。 其他端口号可供一般使用 。 应用程序可以选择可用的端口号, 也可以在操作系统中进行核分配 。

      第六,TCP/IP网络中的数据流

      在图表中,应用层的数据传递到传输层,该层在数据中添加一个 TCP 或 UDP 信头以标记所使用的传输协议。合并的数据传递到 IP 网络层,添加IP 信头以标记发送和接收主机。合并的数据随后传输到网络链层,将数据分为多个框架,并添加发送和接收网络在物理网络之间传输的地址。IP 地址到网络地址的地图由地址解析协议(ARP 1982年)执行。在接收端,数据编码程序是相反的。Each 层通过删除数据头、重新组装数据并将数据传输到前一级的方式删除收到的数据。Send the 应用程序的原始数据将最终传递给接收者的相应应用程序。

      7.套接字编程

      (1)套接字地址

      struct sockaddr_in {
      sa_family_t sin_family; // AF_INET for TCP/IP
      // port number
      in_port_t sin_port;
      struct in_addr sin_addr;// IP address );
      // internet address struct in_addr {
      // IP address in network byte order
      s_addr;
      uint32_t
      );

      在Socket地址结构框架内,
      · TCP/IP网络的Sin_Family总是设于AF_INET。

      • Sin_port仓库港口号,按网络字节的顺序排列。

      * Sin addr 是按网络字节顺序排列的主机 IP 地址。

      (2)套接字API

      服务器必须构造套接字, 并将其绑在带有服务器 IP 地址和端口号的套接字地址上。 它可以使用预设端口号码, 或者使操作系统能够选择端口号码( 如果罪过端口为零 ) 。 为了连接服务器, 客户端必须创建一个套接字 。 对于 UPD 设置, 您可以将其附加到服务器 地址构建器上。 对于 UPD 设置, 您可以将套接字附加到服务器 地址和端口号的套接字地址上。 它可以使用预设端口号码, 或者使操作系统能够选择端口号( 如果罪过端口为零 ) 。 为了连接服务器, 客户端口必须创建套接字。 For UPD 设置, 您可以将其附加到服务器地址 。

      (3) TCP/UDP捆包

      为了发送/接收数据报告,UDP Socket使用Sendto(/ recvfrom)发送/接收数据报告。

      ssize_t sendto(int soCkfd,const void *buf,size_t len,int flags,
      const struct sockaddr *dest_addr,socklen_t addrlen);
      ssize_t recvfrom(int sockfd,void *buf,size_t len,int flags,
      struct sockaddr *src_addr,socklen_t *addrlen);

      在生成和连接服务器地址后, TCP 服务器使用听( ) 并接受( ) 接收客户的连接 。
      int listen(int sockfd, int backlog);
      后遗迹参数决定等待连接的最大队列长度 。 听 () 将 sockfd 所引用的合成标记为将用来接收连接的合成 。
      int accept(int sockfd, struct sockaddr *addr, socklen t *addrlen);

      (4) 通用套件地址结构

      sockaddr 是一个常见的 Socket 地址结构 。

      struct sockaddr
      {
      uint8_t           sa_len;
      sa_family_t       sa_family;
      char              sa_data[14];
      };
      IPv6套接字地址结构
      IPv6套接字地址结构在<netinet/in.h>头文件中定义
      struct in6_addr
      
      {
      
      unit8_t s6_add[16];
      };
      #define SIN6_LEN
      struct sockaddr_in6
      { 
      uint8_t           sin6_len;
      sa_family_t       sin6_family;
      in_port_t         sin6_port;
      uint32_t          sin6_flowinfo;
      struct in6_addr   sin6_addr;
      uint32_t          sin6_scope_id;
      };

      新的struct sockaddr_storage足以容纳系统所支持的任何套接字地址结构。sockaddr_storage结构在<netinet/in.h>头文件中定义

      struct sockaddr_storage
      {
      uint8_t       ss_len;
      sa_family_t   ss_family;
      };

      8.字节排序函数

      末端,小端和大端(内存中两个字字节)

      运算器(小半年):在起始地址中保留低顺序字节。

      大(大) : 将高阶字节保留在起始地址 。

      主机字节顺序:某一系统中使用的字节顺序。

      输出字节序的程序:

      #iclude"unp.h"
      int main(int argc,char **argv)
      {
        union{
           short   s;
           char    c[sizeof(short)];
              }un;
      un.s=0x0102;
      printf("%s:",CUP_VENDOR_OS);
      if(sizeof(short)==2){
          if(un.c[0]==1&&un.c[1]==2)
                  printf("big-endiann");
          else if (un.c[0]==2&&un.c[1]==1)
                  printf("little-endiann");
          else
                  printf("unknownn");
      }else
            printf("sizeof(short)=%dn",sizeof(short));
      exit(0);
      }

      9.字节操纵函数

      bzero: bzero 重置目标字节显示的字节数为零。 此函数经常用于将包件地址结构重置为零 。

      bocpy: 将给定数目的字节从源移到目标字节字符串 。

      bcmp:比较两个随机字节字符串,如果返回值相同,则返回 0;否则,返回值为非-0。

      矩形 : 作为 c, 输入目标字节字符串中显示的字节数 。

      菜单: 比较两个随机字符串, 返回一个大于或小于0的非零值, 取决于第一个变量字节 。

      IPv4 兼容 nint_pton 函数的基本定义 :

      int inet_pton(int family,const char *strptr,void *addrptr)
      {
          if(family==AF_INET)
          {
               struct in_addr  in_val;
          if(inet_aton(strptr,&in_val))
          {
              memcpy(addrptr,&in_val,sizeof(struct int_addr));
              return(1);
          }
          return(0);
          }
          errno=EAFNOSUPPROT;
          return(-1);
      }
      

      三、最有收获的内容

      Web和CGI编程

      万维网或万维网是互联网上使用超文本传输协议(RFC 2616 199)进行信息交流的资源和用户的结合。 自1990年代初期以来,随着因特网能力的不断增强,万维网已成为全世界人民日常生活中不可或缺的一部分。 因此,了解这一技术对学生的计算机科学非常重要。 在本节中,我们将介绍HTTP和网络程序的基本知识。Web编程通常包括参与网络开发的文字、标记和编码,包括网络内容、网络客户和服务器脚本以及网络安全。 在狭义上,网络编程是指创建和维持网页。 网络编程中最常用的语言是HTML、XHTML、JavaScript、 Perl5和PHP。

      Http编程模型

      HTTP是互联网应用程序的服务器客户协议,在TCP上运行,因为它需要可靠的文件传输。 图13描述了HTTP的编程模式。

      在 HTTP 中, 客户可以发送多个 URL, 并向不同的 HTTP 服务器发送请求。 客户维持与特定服务器的永久连接既不必要也不可取。 客户仅为发送请求而与服务器连接, 在发送时将关闭连接。 类似地, 服务器仅为发送回复而连接到客户机, 发送后, 连接将再次关闭。 每一个请求或回复都要求单独连接。 这意味着 HTTP 是一个无效的协议, 因为不需要在连续的请求或回复之间保持任何信息。 NAturally, 这将导致巨大的系统成本和效率。 为了弥补这种缺乏状态信息的情况, HTTP 服务器和客户可以使用 cookie 来提供和维护它们之间的某些状态信息 。

      Web界面

      网页是 HTML 标记语言的文件。 网页文件通过可在 Web 浏览器上解释和显示的 HTML 组件序列来描述网页的结构。 comon 网络浏览器包括 Internet Explorer、 Firefox、 Google Chrome 等。 创建网页等于用 HTML 元素作为建筑块来制作文本文件。 它比编程要多, 不仅仅是文书工作 。

      CGI编程

      互联网服务器不必保留数百万个静态网页文件来回应客户的要求,而是通过动态制作网页来回应客户的要求。

      客户端提交请求, 通常为 HTML 格式, 包括服务器运行的 CGI 程序输入和名称 。 收到请求后, httpd 服务器将有一个子程序执行 CGI 程序 。 CCGI 可以查询数据库系统, 如 MySQL, 使用用户输入来生成 HTML 文件, 取决于用户输入 。 当子进程完成后, httpd 服务器将由此产生的 HTML 文件发回客户端 。

      四、实际联系(剪页、代码链接)

      代码链接:

      https://gitee.com/two_thousand_and_thirteen/zx-code/issues/I4J8R1

      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/types.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
      #include <arpa/inet.h>
      #include <time.h>
      #include <string.h>
      #include <unistd.h>
      #define MAXLINE 256
      
      #define PORT 7777
      
      void sys_err(char *msg){
      
      perror(msg);
      
      exit(-1);
      
      }
      
      int main(int argc , char **argv){
      </span><span style="color: #0000ff;">int</span><span style="color: #000000;"> sockFd,n;
      </span><span style="color: #0000ff;">char</span><span style="color: #000000;"> recvLine[MAXLINE];
      </span><span style="color: #0000ff;">struct</span><span style="color: #000000;"> sockaddr_in servAddr;
      
      </span><span style="color: #0000ff;">if</span> (argc != <span style="color: #800080;">2</span><span style="color: #000000;">) {
          sys_err(</span><span style="color: #800000;">"</span><span style="color: #800000;">usage: a.out &lt;IPaddress&gt;</span><span style="color: #800000;">"</span><span style="color: #000000;">);
      }
      
      sockFd</span>=socket(AF_INET,SOCK_STREAM,<span style="color: #800080;">0</span><span style="color: #000000;">);
      
      
      memset(</span>&amp;servAddr,<span style="color: #800080;">0</span>,<span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(servAddr));
      
      servAddr.sin_family </span>=<span style="color: #000000;"> AF_INET;
      servAddr.sin_port </span>=<span style="color: #000000;"> htons(PORT);
      </span><span style="color: #0000ff;">if</span> (inet_pton(AF_INET,argv[<span style="color: #800080;">1</span>],&amp;servAddr.sin_addr) &lt;= <span style="color: #800080;">0</span><span style="color: #000000;">) {
      
          sys_err(</span><span style="color: #800000;">"</span><span style="color: #800000;">inet_pton error</span><span style="color: #800000;">"</span><span style="color: #000000;">);
      }
      
      connect(sockFd,(</span><span style="color: #0000ff;">struct</span> sockaddr *)&amp;servAddr,<span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(servAddr));
      
      
      </span><span style="color: #0000ff;">while</span>((n=read(sockFd,recvLine,MAXLINE)) &gt;<span style="color: #800080;">0</span><span style="color: #000000;"> ){
          recvLine[n] </span>= <span style="color: #800000;">'</span><span style="color: #800000;"></span><span style="color: #800000;">'</span><span style="color: #000000;">;
          </span><span style="color: #0000ff;">if</span>(fputs(recvLine,stdout) ==<span style="color: #000000;"> EOF){
              sys_err(</span><span style="color: #800000;">"</span><span style="color: #800000;">fputs error</span><span style="color: #800000;">"</span><span style="color: #000000;">);
          }
      }
      </span><span style="color: #0000ff;">if</span>(n &lt;<span style="color: #800080;">0</span><span style="color: #000000;">){
          sys_err(</span><span style="color: #800000;">"</span><span style="color: #800000;">read error</span><span style="color: #800000;">"</span><span style="color: #000000;">);
      }
      </span><span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;
      
      }

      代码运行截图:

      五、问题与解决思路

      Linux一揽子方案拟定工作的五大风险是什么?

      1. 无视回返状况。

      第一种危险是显而易见的,但它是新来者发育过程中最常见的错误。 如果您忽略函数的返回状态, 您可能会在函数失败或部分成功时丢失。 这反过来会传播错误, 并使得问题的原因难以发现 。

      检查列表 1 中的插座发送函数示例。 抓取并检查每个返回状态, 而不是忽略它们 。

      一. 无视API函数返回的状况。

      int status, sock, mode;
        / Create a new stream (TCP) socket /sock =
        socket( AF_INET, SOCK_STREAM, 0 );
        ...status = send( sock, buffer, buflen, MSG_DONTWAIT );
        if (status == -1) {/ send failed /printf( "send failed: %sn",?
        strerror(errno) );
        } else {/ send succeeded -- or did it? /}

      列表 1 跳入一个功能段, 以完成对发送操作的合成( 通过合成传送数据) 。 函数的错误状态会被收集和检查, 但此示例忽略了以不间断模式发送的特性( 由 MSG_ DontWAIT 标识驱动 ) 。

      传输 API 函数有三个潜在返回值: 如果数据在传输队列中成功排队, 返回 0; 如果数据在传输队列中成功排队, 返回 1; 如果数据在传输队列中成功排队, 返回 2。 如果队列失败, 返回 - 1( 失败的原因可以从错误字段中推导出来)。 如果函数被引用, 而不是所有字符都可以排队, 最后返回值是发送的字符数 。

      由于MSG_DONTWAIT传输的变量的不间断性质,函数在传输所有数据、某些数据或无数据后返回。 在此忽略返回状态将导致发送不全并导致数据丢失。

      2. 完成相互综合。

      UNIX中令人感兴趣的部分是,几乎所有文件都可被视为文件。文件本身、目录、管道、设备和合成都作为文件处理。这是一个独特的抽象概念,这意味着全部API都可以在各种各样的设备中使用。

      考虑读取 API 方法, 读取文件中指定的字节数。 读取函数返回读取的字节数( 您要求的最大值); - 1, 错误; 或 0, 如果文件达到结尾值 。

      如果读操作已完成,且在包装单词上实现了 0 的返回值,则表示近端 API 方法被调用到远程包装单词的对等级别。 指令与文件读取相同 - 没有多余的数据可以由描述符读取( 见表 2)。

      2. 正确处理读取 API 电话的返回值。

       int sock, status;sock = socket( AF_INET, SOCK_STREAM, 0 );
        ...status = read( sock, buffer, buflen );
        if (status > 0) {/ Data read from the socket /} else if (status == -1)
        {/ Error, check errno, take action... /} else if (status ==
        0) {/ Peer closed the socket, finish the close /close( sock );
        / Further processing... /}

      同样,使用写 API 函数,您可以识别封闭的对等器套件。在此情况下,收到SIGPIPE 信号,或者如果信号被屏蔽,写函数返回 -1, 并设置 EPIPE 错误 。

      使用地址(EADDININE)时出错

      3. 为避免与处理有关的错误,使用SO_REEADD。

        int sock, ret, on;struct sockaddr_in servaddr;
        / Create a new stream (TCP) socket /sock =
        socket( AF_INET, SOCK_STREAM, 0 ):
        / Enable address reuse /on = 1;
        ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR,
        &on, sizeof(on) );/* Allow connections to
        port 8080 from any available interface
        */memset( &servaddr, 0, sizeof(servaddr) );
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
        servaddr.sin_port = htons( 45000 );
        /* Bind to the address (interface/port)
        */ret = bind( sock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

      通过使用 SO_REUSEADR 选项,绑定 API 功能能够快速重新使用地址。

      4. 结构数据传输

      袜子是交付无结构的二进制字节流或 ASCII 数据流( 例如) 的理想选择。 HTTP 上的 HTTP 站点或 SMTP 上的电子邮件 。 尽管如此, 试图传输软件包上的二进制数据会使问题复杂化。

      例如,如果您想要传达一个整数, 您能否确定接收者会以同样的方式解释它? 在同一结构下运行的程序可能依靠他们共享的平台来理解同样类型的数据。 然而, 当客户在高优先IBM PowerPC上运行时将32位整数传送到低优先级 Intel x86 时, 会发生什么情况? 字节排序将得出错误的解释 。

      5.TCP 5.TCP的框架同步预测

      TCP 不提供框架同步, 这使得以字节为基础的协议更加理想。 这是对 TCP 和 UDP( 用户数据表协议) 的关键区别。 UDP 是一个以信息为导向的协议, 维护发送者和接收者之间的信息边界。 TCP 是一个以流动为导向的协议, 假设交换的数据没有结构。

      5. tcppdump 工具的使用模式

        Display all traffic on the eth0 interface for
        the local host$ tcpdump -l -i eth0Show all traffic
        on the network coming from or going
        to host plato$ tcpdump host platoShow all HTTP traffic
        for host camus$ tcpdump host camus and (port http)View
        traffic coming from or going
        to TCP port 45000 on the local host$ tcpdump tcp port 45000

      tcpdump 和 tcpplow 程序包括多种选项,包括设计复杂过滤表达式的能力。关于这些工具的更多信息,请参阅下面的参考。

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/13712.html

          热门文章

          文章分类