Python学习----网络编程

网络:网络就是实现资源共享和信息传递的虚拟平台,我们可以编写基于网络通信的程序。比如socket编程,web开发

Socket编程

Socket是程序之间通信的一个工具,好比显示生活中的电话,你知道了对方的电话号码之后,需要使用电话进行通讯。同理你知道了对方的ip 地址和端口号之后,你需要使用socket进行通信。

在通信之前,我们需要选择网络通讯协议(网络传输方式)。保证程序之间按照指定的规则进行数据通信。

TCP

TCP 简称 传输控制协议,它是一种面向连接的、可靠的、基于字节流的传输层通信协议。
1、面向连接:通信双方必须先建立好连接才能进行数据传输,并且双方都会为此连接分配必要资源用来记录连接的状态和信息。当数据传输完成之后,双方必须断开此连接,以释放系统资源。
2、可靠传输:

TCP采用发送应答机制:
	通过TCP这种方式发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段发送成功
超时重传
	发送端发送一个报文之后就会启动定时器,如果指定的时间内没有得到应答就会重新发送这个报文
错误校验
	TCP用一个 校验和 函数来校验数据是否有错误,在发送和接收时都要计算 校验和
流量控制和阻塞管理
	流量控制用来避免发送端发送过快而使得接收方来不及接收

通信步骤:
1、创建连接
2、传输数据
3、关闭连接

python编码转换

在网络中传输的数据都是二进制的数据,所以我们在发送数据的时候需要将数据转换为二进制,到达目的地之后再将二进制数据转换回来。
转码: encode
解码: decode

TCP客户端程序开发

开发流程:
在这里插入图片描述

开发步骤:
1、导入socket模块
import socket
2、创建客户端socket对象
socket.socket(AddressFamily , Type)
AddressFamily:IP地址类型,分为Ipv4和Ipv6
type:传输协议类型
3、建立连接
connect
4、数据传输
send:发送数据
recv:接收数据
close:关闭连接
代码演示:

import socket

if __name__ == '__main__':
    # 1、创建客户端套接字对象
    # 静态常量  AF_INET代表Ipv4  SOCK_STREAM代表TCP协议
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2、和服务器建立套接字连接。参数是元组,指定ip和端口
    tcp_client_socket.connect(("127.0.0.1", 8888))
    # 3、发送数据,需要进行编码
    tcp_client_socket.send("hello".encode(encoding="utf-8"))
    # 4、接收数据,每次接收数据的大小,单位是字节,recv会阻塞等待数据到来,如果你不需要接收数据,那就跳过这步
    recv_data = tcp_client_socket.recv(1024)
    print(recv_data.decode())  # 默认utf-8解码,可省略不写
    # 5、关闭客户端套接字
    tcp_client_socket.close()

TCP服务端程序开发

1、创建服务端套接字对象
2、绑定IP地址和端口号,通过bind()函数完成
3、设置监听 , listen()函数
4、等待接收客户端连接请求
5、接收数据
6、发送数据
7、关闭套接字

开发步骤:
1、导入socket模块
import socket
2、创建服务端socket对象
socket.socket(AddressFamily , Type)
AddressFamily:IP地址类型,分为Ipv4和Ipv6
type:传输协议类型
3、绑定ip地址和端口
bind
4、设置监听
listen
5、等待接收客户端的连接请求
accept
发送数据
6、数据传输
send:发送数据
recv:接收数据
close:关闭连接

代码演示:

import socket

if __name__ == '__main__':
    # 1、创建服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


    # 设置端口复用,关闭程序之后,电脑端口释放需要时间,但是实际上是已经释放了,
    # 但程序认为没有释放,所以关闭程序之后立即启动会报错
    # 直接进行强制复用
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

    # 2、绑定ip地址和端口号
    # tcp_server_socket.bind(("192.168.31.59", 8888))
    tcp_server_socket.bind(("", 8888))  # 不设置的话,会自动填充本机ip地址
    # 3、设置监听
    tcp_server_socket.listen(128)  # 参数128:代表服务端等待排队连接的最大数量,超出的限制的连接就丢弃
    # 4、等待客户端请求
    # 这步会阻塞等待,如果接收到请求,返回一个用以和客户端通讯的socket,和客户端地址
    # 上面创建的socket只是监听,不会发送数据
    connect_socket, ip_port = tcp_server_socket.accept()
    print("客户端地址:", ip_port)
    # 5、接收数据
    recv_data = connect_socket.recv(1024)
    print("接收到的数据:", recv_data.decode())
    # 6、发送数据
    connect_socket.send("客户端数据已收到".encode())
    # 7、关闭套接字
    connect_socket.close()
    tcp_server_socket.close()
socket的发送和接收缓冲区

当创建一个TCP socket对象的时候,会有一个发送缓冲区和一个接收缓冲区,这个发送和接收缓冲区就是内存中的一片空间。

当你要发送消息时,先将消息存放在缓冲区,当消息达到一定的数量之后再一次性进行发送。

send原理解析:
问题:send是不是直接把数据发送给服务端?
不是,要想发送数据,必须得通过网卡发送数据,应用程序无法直接通过网卡发送数据,它需要调用操作系统接口,也就是说,应用程序把发送得数据先写入到发送缓冲区(内存一片空间),再由操作系统控制网卡把发送缓冲区得数据发送给服务端网卡。

recv原理解析:
问题:recv是不是直接从客户端接收数据?
不是,应用程序无法直接通过网卡接收数据,它需要调用操作系统接口,由操作系统通过网卡接收数据,把接收得数据写入接收缓冲区(内存一片空间),应用程序再从接收缓冲区获取客户端发送得数据。

在这里插入图片描述

Demo多任务版TCP服务端程序
import socket
import threading


def tcp_server_thread(connect_socket, ip_port):
    print("客户端地址:", ip_port)
    # 5、接收数据
    recv_data = connect_socket.recv(1024)
    print("接收到的数据:", recv_data.decode())
    # 6、发送数据
    connect_socket.send("客户端数据已收到".encode())
    # 7、关闭套接字
    connect_socket.close()


if __name__ == '__main__':
    # 1、创建服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 设置端口复用,关闭程序之后,电脑端口释放需要时间,但是实际上是已经释放了,但程序认为没有释放,所以关闭程序之后立即启动会报错
    # 直接进行强制复用
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 2、绑定ip地址和端口号
    # tcp_server_socket.bind(("192.168.31.59", 8888))
    tcp_server_socket.bind(("", 8888))  # 不设置的话,会自动填充本机ip地址
    # 3、设置监听
    tcp_server_socket.listen(128)  # 参数128:代表服务端等待排队连接的最大数量,超出的限制的连接就丢弃
    while True:
        # 4、等待客户端请求
        # 这步会阻塞等待,如果接收到请求,返回一个用以和客户端通讯的socket,和客户端地址
        # 上面创建的socket只是监听,不会发送数据
        connect_socket, ip_port = tcp_server_socket.accept()
        server_thread = threading.Thread(target=tcp_server_thread, args=(connect_socket, ip_port))
        server_thread.start()
    tcp_server_socket.close()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值