Socket 传情:用 Python 编织 TCP 网络

这篇具有很好参考价值的文章主要介绍了Socket 传情:用 Python 编织 TCP 网络。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

参考

项目 描述
Python 官方文档 https://docs.python.org/zh-cn/3/
搜索引擎 Google 、Bing

描述

项目 描述
操作系统 Windows 10 专业版
PyCharm 2023.1 (Professional Edition)
Python 3.10.6

TCP 服务器端与 TCP 客户端通信的基本流程

Socket 传情:用 Python 编织 TCP 网络

服务器端

  1. 创建一个监听套接字对象,指定地址族(IPV4IPV6)和套接字类型(TCP 套接字UDP 套接字)。

  2. 通过使用 bind() 方法为监听套接字指定套接字地址。

  3. 调用 listen() 方法以指示监听套接字 开始 对客户端的连接请求进行监听。

  4. 通过调用 accept() 方法接受客户端的连接请求,该方法将返回一个连接套接字及客户端套接字的套接字地址。

  5. 通过连接套接字与客户端进行通信,使用 recv() 方法接收客户端发送的数据,使用 send() 方法向客户端发送响应。

  6. 重复步骤 5,直到通信完成。

  7. 关闭服务器套接字。

Socket 传情:用 Python 编织 TCP 网络

客户端

  1. 创建一个客户端套接字对象,并为该套接字指定 地址族套接字类型

  2. 调用 connect() 方法通过服务器的监听套接字向服务器端发起连接请求。

  3. 通过客户端套接字与服务器进行通信,使用 send() 向服务器发送数据,使用 recv()方法接收服务器端返回的响应。

  4. 重复步骤 3,直到通信完成。

  5. 关闭客户端套接字。

使用 socket 实现 TCP 服务器端

实现监听套接字

socket.socket()

socket 模块中,socket() 类用于创建 套接字对象

class socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, fileno=None)

其中:

参数 描述
family 指定地址族类型,默认为 IPV4socket 模块提供常量 socket.AF_INETsocket.AF_INET6 分别用于指定地址族 IPV4IPV6
type 指定套接字类型,默认为 TCP 套接字socket 模块提供常量 socket.SOCK_STREAMsocket.SOCK_DGRAM 分别用于指定 TCP 套接字与 UDP 套接字。
proto 指定套接字所使用的传输层协议,默认值为 0。使用 默认值 0 意味着 socket() 将依据参数 familytype 的值自动选择合适的传输层协议。socket 模块提供了常量 socket.IPPROTO_TCPsocket.IPPROTO_UDP 分别用于指定传输层协议 TCPUDP
fileno 指定套接字所使用的 文件描述符(文件描述符是操作系统中用于标识打开文件或套接字的整数值),使用同一文件描述符的 套接字对象将 被视为同一个 套接字
Socket().bind()

socket 对象的 bind() 函数用于为 监听套接字 指定 套接字地址。在 socket 编程中,套接字地址通常使用 元组 进行存储。其中,元组的第一个元素为 IP 地址,元组中的第二个元素为 端口号

IP 地址的选择

假设我们有一台服务器,具有两个网络接口 eth0eth1,分别对应 IP 地址 192.168.1.1010.0.0.5

本地回环地址

如果我们使用 127.0.0.1localhost 作为监听套接字的 IP 地址,那么监听套接字将只监听来自 本地回环接口(Loopback Interface) 的连接请求,这意味着只有本机上的进程可以通过 localhost127.0.0.1 与服务器建立连接,而来自其他网络接口的连接请求将被忽略。
本地回环接口是一个特殊的网络接口,通常用于本机内部的通信。本地回环接口的 IP 地址 通常设置为127.0.0.1,该 IP 地址通常被称为 本地主机地址
当监听套接字的监听地址被设置为 127.0.0.1 时,该套接字将仅监听来自本地回环接口的连接请求,而不会监听来自其他网络接口的连接。

注:

通过本地回环地址 127.0.0.1localhost 访问主机时,数据不需要经过物理网络接口进行传输。

某一特定 IP 地址

如果我们使用某一特定的 IP 地址,如 192.168.1.10 作为监听套接字的 IP 地址,那么监听套接字将仅监听来自 192.168.1.10 的连接请求。对于来自 10.0.0.5 的连接请求不予理会。

空字符串

当将一个 空字符串 作为套接字地址中的 IP 地址传递给 bind() 函数时,该函数会将监听套接字绑定到 系统上所有可用的网络接口,这意味着监听套接字将监听所有来自可用的网络接口上的连接请求。

如果我们使用 空字符串 作为监听套接字地址的 IP 地址,那么监听套接字将监听来自网络接口 eth0eth1本地回环接口 的连接请求。

Socket().listen()

socket 对象的 listen() 方法的作用是告诉操作系统该套接字应该 开始监听传入的连接请求。一旦调用了 listen() 方法,该套接字就将进入监听状态,并开始等待客户端的连接请求。

Socket().listen(backlog=5)

listen() 方法接收一个参数 backlog,用于指定操作系统在未接受连接之前可以排队等待的 最大连接数
如果等待被处理的连接请求的数量即将超过最大连接数,则后续的客户端连接请求 可能 将被 拒绝。参数 backlog 的取值为一个 大于或等于零的整数,若参数值小于零,则该参数的 实际值 将为零。

监听套接字的实现
import socket as sk


# 规定监听套接字地址
HOST = ''
PORT = 8080

# 创建监听套接字
monitor = sk.socket()
# 为监听套接字指定套接字地址
monitor.bind((HOST, PORT))
# 启用监听套接字以监听来自客户端的连接请求
monitor.listen(100)

# 向控制台中输出服务器当前的运行状态
print(f'The Server is running at {"localhost" if HOST == "" else HOST}: {PORT}')

实现连接套接字

Socket().accept()

socketaccept() 方法的作用是在套接字进入监听模式后,阻塞当前线程并等待客户端的连接请求。一旦有客户端连接请求到达,accept() 方法将返回一个 连接套接字对象客户端套接字的地址。通过连接套接字对象,服务器端将能够与客户端进行通信。

conn.send()

连接套接字对象的 send() 方法 的作用是将数据发送到 客户端套接字,以便将数据传输到远程主机。send() 方法将返回已发送数据的 字节数,若因为某些不可控因素导致数据 仅部分 发送至目标套接字,则程序需要自行处理数据未完全发送的情况。

连接套接字对象还具有一个与 send() 方法类似的方法 sendall()sendall() 方法的作用是将指定的数据发送到与当前套接字连接的另一端套接字。与 send() 方法不同的是,sendall() 方法会自动处理数据仅部分发送的情况,并保证所有数据都被发送出去。若数据无法 全部 发送至目标套接字,则该方法将 抛出异常

注:

使用 send()sendall() 方法仅能够向远程主机传递二进制数据。通过调用字符串对象的 encode() 方法将能够得到该字符串对象的二进制数据形式。

监听套接字的实现
# 创建连接套接字
conn, addr = monitor.accept()

# 在接收到来自客户端的连接请求后
# 向控制台中输出相关提示信息。
print(f'The Server has received a connection from {addr[0]}: {addr[1]}')

# 向客户端发送成功连接至服务器的提示信息
# 在发送数据前需要通过 encode() 方法对发送数据进行 UTF-8 编码操作,
# 以将字符串类型数据转换为二进制数据。
conn.send('Can I help you?'.encode())

数据收发

conn.recv()

连接套接字对象的 recv() 方法,能够接收来自 客户端套接字 的数据,并将接收到的数据存储在指定大小的 缓冲区 中。

recv() 方法允许传递一个参数,用以指定存储数据的缓冲区大小(以 字节 为单位)。如果接收到的数据大小超过了设定缓冲区大小,那么服务器端将仅能够接收到缓冲区大小的数据。因此在实际使用时,通常需要在一个循环中多次调用recv()方法,直到接收到所需的所有数据。

注:

recv() 方法是一个 阻塞调用,即在没有接收到数据时,当前线程将会被阻塞,直到接收到数据或发生错误。可以通过调用 socket.setdefaulttimeout() 函数设置套接字的超时时长以控制阻塞的行为,当阻塞时长大于设定的超时时长时,recv() 方法将抛出异常。

具体实现
message = 'Content From Client'
while True:
    # 接收信息并将其输出至控制台中。
    # 由于接收到的数据为二进制数据,故在使用接收到的数据前
    # 需要使用 decode() 方法对其进行解码操作。
    message = conn.recv(9999).decode()
    print(f'【Client】 {message}')

    # 在客户端发送 Bye(不考虑大小写)后进行响应并终止循环
    if message.lower() == 'bye':
        conn.send('Bye'.encode())
        break

    # 通过控制台指定发送数据并通过 send() 函数将其发送至客户端
    think = input('>>> ')
    conn.send(think.encode())

关闭套接字

可以通过调用套接字对象的 close() 方法来关闭套接字及其现有的连接。
在套接字无需使用时,关闭套接字有助于防止资源泄露和保持系统的稳定性。如果不及时关闭套接字,可能会导致资源的浪费和应用程序的异常行为。此外,关闭套接字还可以 确保连接的清理和释放,以便其他应用程序能够使用 相同的端口 进行通信。

# 关闭连接套接字
conn.close()

# 关闭监听套接字
monitor.close()

代码总汇

import socket as sk


# 规定监听套接字地址
HOST = ''
PORT = 8080

# 创建监听套接字
monitor = sk.socket()
# 为监听套接字指定套接字地址
monitor.bind((HOST, PORT))
# 启用监听套接字以监听来自客户端的连接请求
monitor.listen(100)

# 向控制台中输出服务器当前的运行状态
print(f'The Server is running at {"localhost" if HOST == "" else HOST}: {PORT}')

# 创建连接套接字
conn, addr = monitor.accept()

# 在接收到来自客户端的连接请求后
# 向控制台中输出相关提示信息。
print(f'The Server has received a connection from {addr[0]}: {addr[1]}')

# 向客户端发送成功连接至服务器的提示信息
# 在发送数据前需要通过 encode() 方法对发送数据进行 UTF-8 编码操作,
# 以将字符串类型数据转换为二进制数据。
conn.send('Can I help you?'.encode())

message = 'Content From Client'
while True:
    # 接收信息并将其输出至控制台中。
    # 由于接收到的数据为二进制数据,故在使用接收到的数据前
    # 需要使用 decode() 方法对其进行解码操作。
    message = conn.recv(9999).decode()
    print(f'【Client】 {message}')

    # 在客户端发送 Bye(不考虑大小写)后进行响应并终止循环
    if message.lower() == 'bye':
        conn.send('Bye'.encode())
        break

    # 通过控制台指定发送数据并通过 send() 函数将其发送至客户端
    think = input('>>> ')
    conn.send(think.encode())

# 关闭连接套接字
conn.close()

# 关闭监听套接字
monitor.close()

使用 socket 实现 TCP 客户端

Socket().connect()

socket 对象的 connect() 方法用于在客户端中通过 客户端套接字 向服务器端的 监听套接字 发起连接请求。

connect() 方法接收一个二元元组作为实参,该元组用于表示服务器端监听套接字的套接字地址。
connect() 方法没有返回值,它会尝试与指定的服务器建立连接。若连接建立失败,该方法将会抛出异常。

具体实现
import socket as sk


# 指定服务器端的监听套接字的套接字地址
HOST = '127.0.0.1'
PORT = 8080

# 创建客户端套接字
client = sk.socket()
# 通过 connect() 方法指定服务器端
# 监听套接字的套接字地址以向服务器端发起连接请求
client.connect((HOST, PORT))

message = 'Content From Server'
while True:
    # 接收信息并将其输出至控制台中。
    # 由于接收到的数据为二进制数据,故在使用接收到的数据前
    # 需要使用 decode() 方法对其进行解码操作。
    message = client.recv(9999).decode()
    print(f'【Server】 {message}')

    # 在服务器端发送 Bye(不考虑大小写)后进行响应并终止循环
    if message.lower() == 'bye':
        # 在发送数据前需要通过 encode() 方法对发送数据进行 UTF-8 编码操作,
        # 以将字符串类型数据转换为二进制数据。
        client.send('Bye'.encode())
        break

    # 通过控制台指定发送数据并通过 send() 函数将其发送至服务器端
    think = input('>>> ')
    client.send(think.encode())

# 关闭客户端套接字
client.close()

TCP 服务器与 TCP 客户端的双向通信

在进行 socket 编程 时,需要注意服务器端与客户端的 运行顺序TCP 服务器端 程序需要先于 TCP 客户端 程序运行。确保服务器先启动并能够对来自客户端的连接请求进行监听,然后客户端再启动并尝试连接到服务器端,这样可以确保服务器能够接受客户端的连接请求并建立有效的通信通道。

Socket 传情:用 Python 编织 TCP 网络

在运行上述 TCP 服务器端与 TCP 客户端实现后,存在如下运行效果。

Socket 传情:用 Python 编织 TCP 网络文章来源地址https://www.toymoban.com/news/detail-490928.html

到了这里,关于Socket 传情:用 Python 编织 TCP 网络的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【socket】从计算机网络基础到socket编程——Windows && Linux C语言 + Python实现(TCP+UDP)

    简单讲一下基础知识,便于后面代码的理解,建议大概浏览一下这一小节内容。这里讲的只是冰山一角,建议大家学习计算机网络相关知识,推荐几本书: 《计算机网络》(谢希仁) 《计算机网络 自顶向下方法》 《计算机网络技术》 《计算机网络基础及应用》 《Linux C从入

    2024年02月08日
    浏览(60)
  • 网络编程:TCP socket

    TCP(Transmission Control Protocol,传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 TCP不

    2024年02月05日
    浏览(48)
  • 【网络编程】TCP Socket编程

    流套接字: 使用传输层TCP协议 TCP: 即Transmission Control Protocol(传输控制协议),传输层协议。 TCP的特点: 有连接 可靠传输 面向字节流 有接收缓冲区,也有发送缓冲区 大小不限 ServerSocket 是 创建TCP服务端Socket 的API。 注意: ServerSocket 只能用于 服务器端。 构造方法: 方法签名

    2024年02月07日
    浏览(49)
  • TCP/IP网络参考模型

    目录 TCP/IP四/五层模型 应用层常见协议——传输数据PDU 传输层协议——传输数据段 端口号 TCP面向连接服务CONS  TCP报文格式 TCP数据传输——ACK确认机制 TCP会话建立——三次握手 TCP会话结束——四次握手 TCP流量控制——滑动窗口协议 TCP可靠传输机制 TCP拥塞控制 UDP无面向连

    2024年02月09日
    浏览(43)
  • 【网络】socket——TCP网络通信 | 日志功能 | 守护进程

    🐱作者:一只大喵咪1201 🐱专栏:《网络》 🔥格言: 你只管努力,剩下的交给时间! 上篇文章中本喵介绍了UDP网络通信的socket代码,今天介绍TCP网络通信的socket代码。 和 udp 的网络通信一样, tcp 通信也需要服务器指定端口号,IP地址同样使用 0.0.0.0 ,以便客户端所有对服

    2024年02月16日
    浏览(49)
  • 网络通信(Socket/TCP/UDP)

    Socket(又叫套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接协议,客户端的IP地址,客户端的端口,服务器的IP地址,服务器的端口。 一个Socket是一对IP地址和端口。 Socket可以看

    2024年01月22日
    浏览(56)
  • 基于TCP的Socket网络编程

    前言: Socket通信是基于TCP/IP协议的通信。在工作和做项目中应用非常广,下面来介绍下Socket网络编程! Socket的介绍 首先,在Socket网络编程中我们要了解两个重要的东西,ip和端口号,一台拥有IP地址的主机可以提供许多服务,比如Web服务、FTP服务、SMTP服务等。这些服务完全

    2024年02月11日
    浏览(45)
  • Unity3D 网络游戏框架(二、同步Socket) 参考连接:Socket 类 (System.Net.Sockets) | Microsoft Learn

    1、Socket.Connect() 2、Socket.Send() 3、Socket.Receive() 在了解完Socket通讯流程图和相关API之后我们来开发客户端代码:  在Unity中添加 两个Button、一个InputField和有Text ,Connect 方法 绑定连接的按钮, Send 方法绑定发送按钮。 Connect :客户端点击连接后会和服务端进行连接,这里面127

    2024年02月16日
    浏览(49)
  • 【网络篇】socket编程——TCP(史上最全)

    目录 一、初始TCP 1.TCP协议特点 2.TCP头:  3.确认应答机制 4.超时重传机制 5.流量控制 6.拥塞控制 (1)TCP 的拥塞控制方法 慢开始 拥塞避免 快重传 快恢复 二、建立连接——三次握手  三、断开连接——四次挥手 四、socket编程 ##客户端API函数 ##服务端API函数 (1)TCP 是 面向连

    2024年02月08日
    浏览(46)
  • TCP/IP(十一)TCP的连接管理(八)socket网络编程

    一  socket网络编程  socket 基本操作函数 bind、listen、connect、accept、recv、send、select、close ①  针对 TCP 应该如何 Socket 编程? ②   listen 时候参数 backlog 的意义? ③  accept 发生在三次握手的哪一步? ④   客户端调用 close 了,连接是断开的流程是什么? ⑤  没有 accept,能建立 T

    2024年02月07日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包