python应用-socket网络编程(1)

目录

1 先简单回顾下客户端和服务端通信的知识

2 服务端常用函数

3 客户端常用函数

4 服务端和客户端都用的函数

5 示例介绍客户端和服务端通信过程

6 建立服务端套接制

7 创建服务端函数socket.create_server()

8 创建客户端套接字

9 客户端连接函数socket.create_connection()

10 socket使用with ... as 上下文管理器

socket 是 Python 标准库中的一个模块,它提供了低级别的网络通信接口。使用 socket 模块,你可以创建客户端和服务器应用程序,以便在网络上进行数据交换。

先简单回顾下客户端和服务端通信的知识

以前我记得面试的时候经常会被问到一个问题:当在浏览器上输入百度域名并回车后,我们能看到浏览器返回了首页的内容,那中间的通信过程是什么?

当然中间经历的过程涉及到了很多通信知识,比如ip地址/tcp协议/http协议/DNS协议等(OSI的七层模型),浏览器的html/js/css等等方方面面,大家可以自行学习。

那要想完成客户端到服务端的tcp连接,首先服务器端要监听ip和port,等待很多个客户端主动发起连接,从而发送数据进行通信。而socket模块的函数就可以支持完成通信过程,我们先介绍下socket的一些常用函数。

服务端常用函数:

**bind(**address)方法用于将套接字绑定到指定的地址。地址通常是一个包含IP地址和端口号的元组,例如 ('localhost', 80)。

**listen(**backlog) 方法用于在服务器端套接字上启用监听,等待客户端的连接。backlog 参数指定了最多可以挂起的连接数。

accept() 方法用于接受一个客户端的连接请求,并返回一个新的套接字对象和客户端的地址。这个方法通常用在服务器端,用于处理多个客户端的连接。

客户端常用函数

connect(address) 方法用于客户端连接到指定的服务器地址。地址是一个包含服务器IP地址和端口号的元组。

服务端和客户端都用的函数

send() 和 sendall()

send(bytes) 方法用于发送数据到连接的套接字。sendall(bytes) 方法也是用于发送数据,但它会尝试发送所有数据,直到没有数据需要发送或发生错误。

recv(bufsize, flags=0) 方法用于接收套接字的数据。bufsize 参数指定了要接收的最大字节数。

**close()**方法用于关闭套接字连接。一旦套接字被关闭,就不能再发送或接收数据。

示例介绍客户端和服务端通信过程

建立服务端套接字

复制代码
import socket
# 创建一个 socket 对象 基于ipv4和tcp
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定到本地地址和端口
server_address = ('localhost', 8080)
server_socket.bind(server_address)
# 开始监听连接
server_socket.listen(1)
print('Waiting for a connection...')
#接收客户端的连接
connection, client_address = server_socket.accept()
print(f'Connection from {client_address}')
#接收客户端发送的数据
data = connection.recv(1024)
print(f'Received {len(data)} bytes from {client_address}')
#解码2进制内容
if data:
print(data.decode())
senddata = data.decode() + ',已收到该消息。'
else:
senddata = '没有收到消息,等待中'
# 往客户端发送数据
connection.sendall(senddata)
#关闭连接
connection.close()

执行该python程序后:服务端会等待客户端连接:

复制代码
Waiting for a connection...

创建服务端函数socket.create_server()

python3.9及以上版本提供了socket.create_server() 函数允许快速创建一个套接字并绑定到指定的地址和端口,同时它还可以选择性地监听套接字。这个函数的原型如下:

socket.create_server(address, family=socket.AF_INET, backlog=None, dualstack_ipv6=False)

参数解释:

  • address:一个元组,包含主机地址和端口号,例如 ('localhost', 8000)。
  • family:地址族,默认为 socket.AF_INET(IPv4),也可以使用 socket.AF_INET6(IPv6)。
  • backlog:指定最多连接数,待处理队列的长度。如果未指定或为 None,则使用默认值。
  • dualstack_ipv6:一个布尔值,如果为 True,并且地址族是 socket.AF_INET6,则创建一个双栈套接字,该套接字可以在 IPv4 和 IPv6 之间透明地工作。

以上创建的服务端可以简化:

复制代码
import socket
server_address = ('localhost', 8080)
#创建服务端socket连接 返回套接字对象
server_socket = socket.create_server(server_address)
print('Waiting for a connection...')
#接收客户端的连接
connection, client_address = server_socket.accept()
print(f'Connection from {client_address}')
#接收客户端发送的数据
data = connection.recv(1024)
print(f'Received {len(data)} bytes from {client_address}')
#解码2进制内容
if data:
print(data.decode())
senddata = data.decode() + ',已收到该消息。'
else:
senddata = '没有收到消息,等待中'
# 往客户端发送数据
connection.sendall(senddata)
#关闭连接
connection.close()

创建客户端套接字

复制代码
import socket
# 创建一个 socket 对象 基于ipv4和tcp
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 连接到刚才的服务端的地址和端口
server_address = ('localhost', 8080)
client_socket.connect(server_address)
# 发送数据 往服务端发送数据
message = 'hello world!'
client_socket.sendall(message.encode())
#等待接收服务端发送的数据
data = client_socket.recv(1024)
print(f'Received {len(data)} bytes {data.decode()}')
# 关闭连接
client_socket.close()

执行客户端python程序后,日志打印如下,接收到了服务端发送的内容:

Received 38 bytes hello world!,已收到该消息。

而服务端也收到了客户端发送的内容:

Received 14 bytes from ('127.0.0.1', 51223)

hello world!

客户端连接函数socket.create_connection()

用于简化创建套接字并与服务器建立 TCP 连接的过程。这个函数会创建套接字,尝试连接到指定的地址,并返回连接好的套接字对象。如果连接失败,它会引发一个异常。

socket.create_connection() 的原型如下:

socket.create_connection(address, timeout=None, source_address=None)

参数解释:

  • address:一个包含服务器地址和端口号的元组,例如 ('localhost', 8080)。
  • timeout:可选参数,指定连接超时时间(秒)。如果连接在超时时间内未完成,则抛出异常。默认为 None,表示不设置超时。
  • source_address:可选参数,一个包含源地址和端口号的元组,用于绑定套接字到特定的本地地址和端口。

socket使用with ... as 上下文管理器

socket这个class支持__enter__() 和__exit__()魔法方法,所以也支持使用with ..as 语句。当程序退出时自动关闭socket连接

复制代码
import socket
with socket.create_connection(('localhost', 8000)) as sock:
  # 使用 sock 发送和接收数据
  pass # 在这里编写你的代码

共勉: 东汉·班固《汉书·枚乘传》:"泰山之管穿石,单极之绠断干。水非石之钻,索非木之锯,渐靡使之然也。"

-----指水滴不断地滴,可以滴穿石头;

-----比喻坚持不懈,集细微的力量也能成就难能的功劳。

----感谢读者的阅读和学习,谢谢大家。

相关推荐
郭庆汝2 小时前
pytorch、torchvision与python版本对应关系
人工智能·pytorch·python
思则变5 小时前
[Pytest] [Part 2]增加 log功能
开发语言·python·pytest
漫谈网络6 小时前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
try2find7 小时前
安装llama-cpp-python踩坑记
开发语言·python·llama
博观而约取8 小时前
Django ORM 1. 创建模型(Model)
数据库·python·django
精灵vector10 小时前
构建专家级SQL Agent交互
python·aigc·ai编程
Zonda要好好学习10 小时前
Python入门Day2
开发语言·python
Vertira10 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
太凉10 小时前
Python之 sorted() 函数的基本语法
python
项目題供诗10 小时前
黑马python(二十四)
开发语言·python