第十三章学习笔记

第13章学习笔记

一、概述

本章论述了TCP/IP和网络编程,分为两个部分。第一部分论述了TCP/IP协议及其应用,具体包括TCP/IP栈、IP地址、主机名、DNS、IP数据包和路由器;介绍了TCP/P网络中的UDP和TCP协议、端口号和数据流;阐述了服务器-客户机计算模型和套接字编程接口;通过使用UDP和TCP套接字的示例演示了网络编程。第一个编程项目可实现一对通过互联网执行文件操作的TCP服务器–客户机,可让用户定义其他通信协议来可靠地传输文件内容。
本章的第二部分介绍了Web和CGI编程,解释了HTTP编程模型、Web页面和Web浏览器;展示了如何配置Linux HTTPD服务器来支持用户Web页面、PHP和CGI编程;阐释了客户机和服务器端动态Web页面;演示了如何使用PHP和CGI创建服务器端动态Web页面。

二、TCP/IP协议

TCP/IP(Comer 1988,2001;RFC1180 1991)是互联网的基础。TCP代表传输控制协议。IP 代表互联网协议。目前有两个版本的IP,即IPv4和IPv6。IPv4使用32位地址,IPv6则使用128位地址。本节围绕IPv4 进行讨论,它仍然是目前使用最多的IP版本。TCP/IP 的组织结构分为几个层级,通常称为TCP/IP堆栈。如图所示为 TCP/IP 的各个层级以及每一层级的代表性组件及其功能。

进程与主机之间的传输层或其上方的数据传输只是逻辑传输。实际数据传输发生在互联网(IP)和链路层,这些层将数据包分成数据帧,以便在物理网络之间传输。下图所示为 TCP/IP 网络中的数据流路径。

三、IP主机和IP地址

  • 主机是支持TCP/IP协议的计算机或设备。每个主机由一个32位的IP地址来标识。为了方便起见32位的IP地址号通常用点记法表示,例如:134121641,其中各个字节用点号分开。主机也可以用主机名来表示,如dnsleecwsuedu。实际上,应用程序通常使用主机名而不是IP地址。在这个意义上说,主机名就等同于IP地址,因为给定其中一个,我们可以通过DNS(域名系统)(RFC1341987RFC10351987)服务器找到另一个,它将IP地址转换为主机名,反之亦然。

  • IP地址分为两部分,即NetworkID字段和HostID字段。根据划分,IP地址分为A~F类。例如,一个B类IP地址被划分为一个16位NetworkID,其中前2位是10,然后是一个16位的HostID字段。发往IP地址的数据包首先被发送到具有相同networkID的路由器。路由器将通过HostID将数据包转发到网络中的特定主机。每个主机都有一个本地主机名 localhost默认IP地址为127001。本地主机的链路层是一个回送虚拟设备,它将每个数据包路由回同一个localhost。这个特性可以让我们在同一台计算机上运行TCP/IP应用程序而不需要实际连接到互联网。

四、IP协议

IP协议用于在 IP主机之间发送/接收数据包。IP尽最大努力运行。IP 主机只向接收主机发送数据包,但它不能保证数据包会被发送到它们的目的地,也不能保证按顺序发送。这意味着IP 并非可靠的协议。必要时,必须在IP 层的上面实现可靠性。下图所示是IP头格式:

五、UDP/TCP

  • UDP(用户数据报协议)(RFC7681980;Comer1988)在IP上运行,用于发送/接收数据报。与IP类似,UDP不能保证可靠性,但是快速高效。它可用于可靠性不重要的情况。
    例如,用户可以使用ping命令探测目标主机,如ping主机名或pingIP地址
    ping是一个向目标主机发送带时间戳UDP包的应用程序。接收到一个pinging数据包后,目标主机将带有时间戳的UDP包回送给发送者,让发送者可以计算和显示往返时间
    如果目标主机不存在或宕机,当TTL减小为0时,路由器将会丢弃pingingUDP数据包。在这种情况下,用户会发现目标主机没有任何响应。用户可以尝试再次ping,或者断定目标主机宕机。在这种情况下,最好使用UDP,因为不要求可靠性。

  • 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793 [1] 定义。
    TCP旨在适应支持多网络应用的分层协议层次结构。 连接到不同但互连的计算机通信网络的主计算机中的成对进程之间依靠TCP提供可靠的通信服务。TCP假设它可以从较低级别的协议获得简单的,可能不可靠的数据报服务。 原则上,TCP应该能够在从硬线连接到分组交换或电路交换网络的各种通信系统之上操作。

六、网络编程

  • 套接字协议及其数据传输特性
int socket(int domain, int type, int protocol);       // domain:采取的协议族,一般为 PF_INET;type:数据传输方式,一般为 SOCK_STREAM;protocol:使用的协议,一般设为 0 即可。
                //成功时返回文件描述符,失败时返回 -1

  • 创建套接字的函数 socket 的三个参数的含义:
    domain:使用的协议族。一般只会用到 PF_INET,即 IPv4 协议族。
    type:套接字类型,即套接字的数据传输方式。主要是两种:SOCK_STREAM(即 TCP)和 SOCK_(即 UDP)。
    protocol:选择的协议。一般情况前两个参数确定后,protocol 也就确定了,所以设为 0 即可。
  • 套接字类型
    同一个协议族可能有多种数据传输方式,因此在指定了 socket 的第一个参数后,还要指定第二个参数 type。
  • SOCK_STREAM 代表的是 TCP 协议,会创建面向连接的套接字,有如下特点:
    1.可靠传输,传输的数据不会消失。
    2.按序传输。
    3.传输的数据没有边界:从面向连接的字节流角度理解。接收方收到数据后放到接收缓存中,用户使用 read 函数像读取字节流一样从中读取数据,因此发送方 write 的次数和接收方 read 的次数可以不一样。
int tcp_socket = socket(PF_INET, SOCK_STREAM, 0);

  • SOCK_DGRAM 代表的是 UDP 协议,会创建面向消息的套接字,有如下特点:
    1.快速传输。
    2.传输的数据可能丢失、损坏。
    3.传输的数据有数据边界:这意味着接收数据的次数要和传输次数相同,一方调用了多少次 write(send),另一方就应该调用多少次 read(recv)。
    4.限制每次传输的数据大小。
int udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
  • 套接字地址结构
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
);

在套接字地址结构中,
● TCP/IP 网络的 sin_family 始终设置为 AF_INET。

● sin_port包含按网络字节顺序排列的端口号。

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

  • 通用套接字地址结构

通用套接字地址结构:sockaddr

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

openeuler实践

代码

运行截图

码云链接https://gitee.com/hai_wen_xu/ls/blob/master/test1.c

问题与解决思路

如何防止SQL注入攻击?

答:
1、使用参数化筛选语句

为了防止SQL注入,用户输入不能直接嵌入到SQL语句中。相反,用户输入必须被过滤或参数化。参数语句使用参数,而不是将用户输入嵌入语句中。在大多数情况下,SQL语句是正确的。然后,用户输入仅限于一个参数。

一般来说,有两种方法可以确保应用程序不易受到SQL注入攻击。一种是使用代码审查,另一种是强制使用参数化语句。强制使用参数化语句意味着在运行时将拒绝嵌入用户输入中的SQL语句。但是,目前对此功能的支持不多。

2、避免使用解释程序,这是黑客用来执行非法命令的手段。

3、防止SQL注入,但也避免一些详细的错误消息,因为黑客可以使用这些消息。标准的输入验证机制用于验证所有输入数据的长度、类型、语句和企业规则。

4、使用专业的漏洞扫描工具。

但是,防范SQL注入攻击是不够的。攻击者现在自动搜索和攻击目标。它的技术甚至可以很容易地应用于其他Web体系结构中的漏洞。企业应该投资于专业的漏洞扫描工具,如著名的Accunetix网络漏洞扫描程序。完美的漏洞扫描器不同于网络扫描器,它专门在网站上查找SQL注入漏洞。最新的漏洞扫描程序可以找到最新发现的漏洞。

posted @ 2021-11-25 16:27  Kevinhw  阅读(14)  评论(0编辑  收藏  举报