python socket网络编程

一:基本概念

  • 服务器:提供服务的一方,负责监听特定端口,等待客户端的连接请求并提供相应服务。
  • 客户端:请求服务的一方,向服务器发起连接请求,与服务器进行数据通信以获取所需服务。
  • 套接字(Socket):网络通信的端点,可理解为网络通信中的一个接口或端口,用于在不同计算机之间发送和接收数据。

三次握手

        TCP 三次握手是 TCP/IP 协议族中,建立 TCP 连接时使用的一种机制,用于确保通信双方都准备好进行数据传输,并且能够正常接收和发送数据。以下是对 TCP 三次握手的详细介绍:

第一次握手:客户端发送 SYN 包

  • 客户端向服务器发送一个带有 SYN(Synchronize Sequence Numbers)标志位的 TCP 数据包,该数据包中还会包含一个随机生成的序列号seq=x。这个数据包的目的是向服务器表明客户端想要建立一个 TCP 连接,并初始化自己的序列号。

第二次握手:服务器发送 SYN+ACK 包

  • 服务器接收到客户端的 SYN 包后,会确认客户端的请求。服务器会向客户端发送一个带有 SYN 和 ACK(Acknowledgment)标志位的 TCP 数据包。其中,SYN 标志位用于初始化服务器到客户端的连接,服务器也会随机生成一个序列号seq=y。同时,ACK 标志位用于确认客户端的 SYN 包,确认号ack=x+1,表示服务器已经成功收到客户端序列号为x的 SYN 包,期望客户端下一次发送的数据从序列号x + 1开始。

第三次握手:客户端发送 ACK 包

  • 客户端收到服务器的 SYN+ACK 包后,会检查确认号是否正确以及 SYN 标志位是否正确等。如果确认无误,客户端会向服务器发送一个带有 ACK 标志位的 TCP 数据包,确认号ack=y+1,表示客户端已经成功收到服务器序列号为y的 SYN 包,期望服务器下一次发送的数据从序列号y + 1开始,而客户端自己的序列号则为seq=x+1。服务器收到这个 ACK 包后,连接就正式建立成功,双方可以开始进行数据传输了。

通过这三次握手,客户端和服务器就能够确认彼此的接收和发送能力,从而建立起可靠的 TCP 连接,为后续的数据传输提供了基础。TCP 三次握手的核心目的就是实现通信双方的同步,确保连接的可靠性和稳定性,防止出现数据丢失或混乱等问题。

二.Python 中的 socket 模块

Python 标准库中的socket模块用于进行 Socket 编程,常用函数和方法如下:

 
  • socket.socket():创建一个新的 Socket 对象。
  • socket.bind(address):将 Socket 绑定到指定的地址(IP 地址和端口号)。
  • socket.listen(backlog):使 Socket 处于监听状态,等待连接请求,backlog指定了连接队列的最大长度。
  • socket.accept():接受连接请求,返回一个新的 Socket 对象和客户端地址。
  • socket.connect(address):连接到指定地址的服务器。
  • socket.send(bytes):发送数据,参数bytes是要发送的字节数据。
  • socket.recv(bufsize):接收数据,bufsize指定了接收数据的缓冲区大小。

三.socket编程

3.1 TCP编程

tcp服务器端

import socket

def start_server():
    # 创建一个TCP/IP Socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定Socket到地址(IP地址和端口号)
    server_address = ('localhost', 65432)
    server_socket.bind(server_address)
    # 监听连接请求
    server_socket.listen(1)
    print('服务器启动,等待连接...')

    while True:
        # 接受连接请求
        client_socket, client_address = server_socket.accept()
        try:
            print('连接自:', client_address)
            # 接收数据
            data = client_socket.recv(1024)
            print('接收到的数据:', data.decode())
            # 发送响应数据
            response = 'HTTP/1.0 200 OK\r\n\r\nHello, World!'
            client_socket.sendall(response.encode())
        finally:
            # 关闭连接
            client_socket.close()

if __name__ == '__main__':
    start_server()

tcp客户端

import socket

def start_client():
    # 创建一个TCP/IP Socket
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接到服务器
    server_address = ('localhost', 65432)
    print('连接到服务器:', server_address)
    client_socket.connect(server_address)
    try:
        # 发送数据
        message = 'GET / HTTP/1.0\r\n\r\n'
        print('发送数据:', message)
        client_socket.sendall(message.encode())
        # 接收响应数据
        data = client_socket.recv(1024)
        print('接收到的数据:', data.decode())
    finally:
        # 关闭连接
        client_socket.close()

if __name__ == '__main__':
    start_client()

3.2 UDP编程

udp服务器端

import socket

udp_server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_server.bind(('127.0.0.1', 9090))
print("UDP服务器启动中...")

while True:
    data, addr = udp_server.recvfrom(1024)
    print(f"来自 {addr} 的消息:{data.decode()}")
    udp_server.sendto(b"消息已收到", addr)

udp客户端

import socket

udp_client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('127.0.0.1', 9090)
message = "你好,服务器!"
udp_client.sendto(message.encode(), server_address)
response, _ = udp_client.recvfrom(1024)
print(f"服务器响应:{response.decode()}")
udp_client.close()

四.模拟ssh协议实现命令执行并返回执行结果

客户端代码

# -*- coding: utf-8 -*-
# Author: s0rin
import socket
import time

def main(target,port):
    sk = socket.socket()
    sk.connect((target,port))
    while True:
        date = input("输入命令>>>")
        sk.send((date.encode()))

        #版本1
        res = sk.recv(1024)
        print("字节长度:",len(res))
        print("执行命令结果:{}".format(res.decode()))

        #版本2
        cmd_ret_bytes_len=sk.recv(1024)
        cmd_res_len = int(cmd_ret_bytes_len.decode())
        recv_num=0
        while recv_num

服务端代码

# -*- coding: utf-8 -*-
# Author: s0rin
import socket
import subprocess
import time
import struct

def main(ip_port):
    sock = socket.socket()
    sock.bind((ip_port))
    sock.listen(10)
    while True:
        conn ,addr = sock.accept()
        print("客户端{}建立连接".format(addr))
        while True:
            cmd = conn.recv(1024)
            if not cmd:
                print(f"{conn.getpeername()}客户端推出")
            print("执行命令",cmd.decode("gbk"))

            #版本1
            cmd_ret_bytes = subprocess.getoutput(cmd).encode()
            conn.send(cmd_ret_bytes)

            #版本2
            cmd_ret_bytes = subprocess.getoutput(cmd).encode()
            print("响应字节数",len(cmd_ret_bytes))
            cmd_ret_bytes_len = str(len(cmd_ret_bytes)).encode()
            conn.send(cmd_ret_bytes_len)
            conn.send(cmd_ret_bytes)

if __name__ == '__main__':
    ip_port = ("127.0.0.1",6666)
    main(ip_port)

你可能感兴趣的:(python安全,网络,python)