网络编程基石课 : 大话网络协议,探究通信奥秘(高の青)

2024-07-05 10:40:31 浏览数 (2)

HTTP(HyperText Transfer Protocol)

简介

HTTP 是一种用于分布式、协作式和超媒体信息系统的应用层协议。它是万维网数据通信的基础。

工作原理

  1. 请求与响应模型:HTTP 是一个基于请求与响应的协议,客户端(通常是浏览器)发送一个请求,服务器返回一个响应。
  2. 无状态协议:HTTP 是无状态协议,每个请求都是独立的,与前后的请求没有直接关系。
  3. 请求方法
    • GET:请求资源。
    • POST:提交数据以处理请求。
    • PUT:上传文件。
    • DELETE:删除资源。
    • HEAD:获取头部信息。
    • OPTIONS:询问服务器支持的 HTTP 方法。
    • PATCH:部分更新资源。

数据传输

  • 请求报文:包括请求行、请求头部、空行和请求数据。
  • 响应报文:包括状态行、响应头部、空行和响应数据。

状态码

  • 1xx:信息性状态码(如 101 Switching Protocols)。
  • 2xx:成功状态码(如 200 OK)。
  • 3xx:重定向状态码(如 301 Moved Permanently)。
  • 4xx:客户端错误状态码(如 404 Not Found)。
  • 5xx:服务器错误状态码(如 500 Internal Server Error)。

HTTP 协议代码示例

以下是一个简单的 Python 代码示例,演示 HTTP 服务器和客户端的通信:

HTTP 服务器
代码语言:txt复制
from http.server import BaseHTTPRequestHandler, HTTPServer

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'Hello from server')

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8080)
    httpd = server_class(server_address, handler_class)
    print('Server running on port 8080')
    httpd.serve_forever()

if __name__ == '__main__':
    run()
HTTP 客户端
代码语言:txt复制
import requests

def http_client():
    response = requests.get('http://127.0.0.1:8080')
    print(f'Status code: {response.status_code}')
    print(f'Response body: {response.text}')

if __name__ == '__main__':
    http_client()

TCP(Transmission Control Protocol)

简介

TCP 是一种面向连接的、可靠的、基于字节流的传输层通信协议。

工作原理

  1. 连接建立:通过三次握手建立连接:
    • 客户端发送 SYN 报文。
    • 服务器回应 SYN-ACK 报文。
    • 客户端回应 ACK 报文,连接建立。
  2. 数据传输:使用滑动窗口机制和确认应答确保数据的可靠传输。
  3. 连接终止:通过四次挥手关闭连接:
    • 一方发送 FIN 报文。
    • 另一方回应 ACK 报文。
    • 另一方发送 FIN 报文。
    • 第一方回应 ACK 报文,连接关闭。

数据传输特点

  • 可靠传输:通过序列号和确认应答机制保证数据不丢失、不重复。
  • 流量控制:通过滑动窗口机制控制数据传输速率。
  • 拥塞控制:通过算法(如慢启动、拥塞避免、快速重传和快速恢复)防止网络拥塞。

TCP 协议代码示例

以下是一个简单的 Python 代码示例,演示 TCP 客户端和服务器的通信:

TCP 服务器
代码语言:txt复制
import socket

def tcp_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('0.0.0.0', 8080))
    server_socket.listen(5)
    print('Server listening on port 8080')

    while True:
        client_socket, addr = server_socket.accept()
        print(f'Connection from {addr}')
        data = client_socket.recv(1024)
        print(f'Received data: {data.decode()}')
        client_socket.sendall(b'Hello from server')
        client_socket.close()

if __name__ == '__main__':
    tcp_server()
TCP 客户端
代码语言:txt复制
import socket

def tcp_client():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(('127.0.0.1', 8080))
    client_socket.sendall(b'Hello from client')
    data = client_socket.recv(1024)
    print(f'Received data: {data.decode()}')
    client_socket.close()

if __name__ == '__main__':
    tcp_client()

UDP(User Datagram Protocol)

简介

UDP 是一种无连接的、不可靠的传输层协议。

工作原理

  1. 无连接:发送方和接收方在通信之前不需要建立连接。
  2. 不可靠传输:数据包发送后不保证到达、不保证顺序、不保证无重复。

数据传输特点

  • 轻量级:头部开销小(8 字节)。
  • 低延迟:适用于实时应用(如视频、音频流)。
  • 无流量控制和拥塞控制:不适用于需要可靠传输的应用。

UDP 协议代码示例

以下是一个简单的 Python 代码示例,演示 UDP 客户端和服务器的通信:

UDP 服务器
代码语言:txt复制
import socket

def udp_server():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server_socket.bind(('0.0.0.0', 8080))
    print('Server listening on port 8080')

    while True:
        data, addr = server_socket.recvfrom(1024)
        print(f'Received data: {data.decode()} from {addr}')
        server_socket.sendto(b'Hello from server', addr)

if __name__ == '__main__':
    udp_server()
UDP 客户端
代码语言:txt复制
import socket

def udp_client():
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    client_socket.sendto(b'Hello from client', ('127.0.0.1', 8080))
    data, addr = client_socket.recvfrom(1024)
    print(f'Received data: {data.decode()}')
    client_socket.close()

if __name__ == '__main__':
    udp_client()

IP(Internet Protocol)

简介

IP 是一种负责在源地址和目的地址之间传输数据包的网络层协议。

工作原理

  1. 数据报传输:IP 将数据分成数据报(Datagram)进行传输,每个数据报独立路由。
  2. 路由选择:根据 IP 地址在不同网络之间选择最佳路径。
  3. 分片与重组:大数据包可能会在传输过程中分片,到达目的地后重组。

数据报结构

  • 头部:包括版本、头部长度、服务类型、总长度、标识、标志、片偏移、生存时间(TTL)、协议、头部校验和、源地址、目的地址。
  • 数据部分:实际传输的数据。

IP 地址

  • IPv4:32 位地址,分为网络部分和主机部分。
  • IPv6:128 位地址,提供更大的地址空间。

工作机制

  • 无连接:每个数据报独立传输。
  • 不可靠:不保证数据报的送达、不保证顺序。

IP 协议代码示例

以下是一个简单的 Python 代码示例,用于解析 IP 数据包:

代码语言:txt复制
import socket
import struct

def parse_ip_packet(packet):
    ip_header = packet[:20]
    iph = struct.unpack('!BBHHHBBH4s4s', ip_header)
    
    version_ihl = iph[0]
    version = version_ihl >> 4
    ihl = version_ihl & 0xF
    ttl = iph[5]
    protocol = iph[6]
    src_address = socket.inet_ntoa(iph[8])
    dest_address = socket.inet_ntoa(iph[9])
    
    print(f'Version: {version}, Header Length: {ihl*4} bytes, TTL: {ttl}')
    print(f'Protocol: {protocol}, Source Address: {src_address}, Destination Address: {dest_address}')

s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)
s.bind(("0.0.0.0", 0))
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
s.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)

while True:
    packet, addr = s.recvfrom(65565)
    parse_ip_packet(packet)

0 人点赞