网站首页 > 技术文章 正文
前言
套接字除了前文用于分析网络地址等功能之外,还可以配置一个服务器,监听到来的消息。
比如你在网络上跟网络机器人聊天,你发送数据到机器人(服务器),然后服务器反馈聊天数据信息给你。当然,机器人的回复还涉及机器学习,但简单的消息反馈涉及的就是套接字的知识。
而且,如果你直接将服务器配置为连接到其他应用的客户端,那么双向通信也可以实现。(比如QQ聊天)
简单的搭建服务器与客户端
既然已经了解了套接字的应用。下面,我们来实现一个简单的单向通信TCP/IP服务器与客户端。
服务器
服务器的原理如下:
1.首先创建一个套接字,TCP是面向流的套接字。故需要使用SOCK_STREAM。
2.然后使用bind()函数将套接字与服务器地址关联(因为我们只是在本地测试,直接将地址设置为127.0.0.1或者localhost,端口号为10000),当然你身边如果有2台电脑设备,可以直接替换局域网的IP地址
3.调用listen()函数将套接字设置为服务器模式,然后无限循环等待,参数为最大排队数
4.在循环中,调用accept()等待客户端的消息连接(当然,这里可以设置最大连接数,超过直接拒绝连接)。如果有客户端进行连接,那么accept()函数会返回一个打开的连接与客户端地址
5.指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据
6.通过sendall()进行回传客户端数据。
7.传回数据后,与当前的客户端通信就算完成了。需要使用close()进行清理
示例代码如下:
import socket
# 1.创建一个套接字,
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.使用bind()函数将套接字与服务器地址关联
sock.bind(('localhost', 10000))
# 3.调用listen()函数将套接字设置为服务器模式
sock.listen(1)
while True:
# 4.调用accept()等待客户端的消息连接
# 如果有客户端进行连接,那么accept()函数会返回一个打开的连接与客户端地址
connection, client_address = sock.accept()
print("连接客户端地址:", client_address)
try:
# 5.指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据
data = connection.recv(1024)
print(data)
if data:
# 6.通过sendall()进行回传客户端数据。
connection.sendall("已接受到数据".encode())
else:
print("客户端没有发送数据,不需要传送数据")
finally:
#7.需要使用close()进行清理
connection.close()
客户端
实现客户端相对来说比服务器要简单的多,因为其不需要监听,只需要连接发送数据即可。客户端实现主要分为:
1.创建一个套接字
2.使用connect()函数连接到服务器
3.通过sendall()向服务器发送数据
4.通过recv()接受服务器传递回的数据
5.交互完成之后,使用close()清理
示例如下:
import socket
# 1.创建一个套接字,
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.使用bind()函数将套接字与服务器地址关联
sock.connect(('localhost', 10000))
try:
msg = b"Are you there?"
# 3.通过sendall()向服务器发送数据
sock.sendall(msg)
# 4.通过recv()接受服务器传递回的数据
data = sock.recv(1024)
print(data.decode())
finally:
# 5.交互完成之后,使用close()清理
sock.close()
运行之后,服务器与客户端交互效果如下:
create_connection(更简易的客户端)
连接服务器除了使用connect()函数之外,其实还有另一个函数create_connection()来连接服务器,它可以省略几个步骤。示例如下:
import socket
# 获取匹配开头字符串的所有属性值
def getConstants(prefix):
return {
getattr(socket, n): n
for n in dir(socket)
if n.startswith(prefix)
}
ipproto_str = getConstants("IPPROTO_")
family_str = getConstants("AF_")
type_str = getConstants("SOCK_")
sock = socket.create_connection(('127.0.0.1', 10000))
print(ipproto_str[sock.proto])
print(family_str[sock.family])
print(type_str[sock.type])
try:
msg = b"Are you there?"
sock.sendall(msg)
data = sock.recv(1024)
print(data.decode())
finally:
sock.close()
运行之后,效果如下:
create_connection()函数的原理是使用getaddrinfo()函数查找候选连接的参数,并返回一个打开的socket。getaddrinfo()函数的讲解在上一篇socket库。
猜你喜欢
- 2025-01-01 Python的一个轻量级桌面GUI开发第三方库:Eel
- 2025-01-01 隐藏彩蛋:你知道python有一个内置的数据库吗?
- 2025-01-01 Python编程绝对初学者指南,一步一步的指南,有示例和实验练习
- 2025-01-01 python服务器socket编程
- 2025-01-01 「大数据」Hana入门
- 2025-01-01 搭建Python自带静态Web服务器
- 2025-01-01 python套接字socket编程搭建简易服务器,完成计算器实例
- 2025-01-01 Python快速搭建HTTP服务
- 2025-01-01 手把手教你使用Python轻松搞定发邮件
- 2025-01-01 软件测试工程师必会技术:Python带你上手WebSocket
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)