Python教程:socket()模块和套接字对象的内建方法

2023-12-28 23:08

本文主要是介绍Python教程:socket()模块和套接字对象的内建方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、socket()模块函数

要使用socket.socket()函数来创建套接字,其语法如下:

socket(socket_family,socket_type,protocol=0)

如上所述,scoket_family不是AF_UNIX就是AF_INETscoket_type可以是SOCK_STREAMSOCK_DGRAM,protocol一般不填,默认值为0.

创建一个TCP/IP套接字,你要这样调用socket.socket():

tcpsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

同样的,创建一个UDP/IP的套接字,你要这样:

udpsock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

由于socket有太多属性,我们一般使用from import socket *语句,将所有属性导入命名空间。

二、套接字对象内建方法

下面是一些套接字对象常用的方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
提示:在运行网络应用程序时,最好在不同的电脑上执行服务器和客户端的程序。

三、创建TCP服务器和TCP客户端

根据上面的介绍,现在我们应该能创建一个完整的通信模型了。下面是理论上的伪代码:

1.套接字理论模型

先来创建一个TCP服务器

#创建一个TCP服务器ss = socket()    #创建服务器套接字ss.bind()           #把地址绑定到套接字上ss.listen()         #监听连接inf_loop:           #服务器无线循环cone,addr = ss.accept()    #接收客户端连接comm_loop:      #通信循环cone.recv()/cs.send()    #对话(接受与发送)cone.close()      #关闭客户端套接字
ss.close()          #关闭服务器套接字(可选)

所有的套接字都用socket.socket()函数来创建。服务器需要“坐在某个端口上”等待请求。所以它们必须要绑定到一个本地的地址上。

由于TCP是一个面向连接的通信系统,在TCP服务器可以开始工作之前,要先完成一些设置。

TCP服务器必须监听(进来的)连接,设置完成之后,服务器就可以进入无线循环了。

一个简单的(单线程的)服务器会调用accept()函数等待连接的到来,

默认情况下,accept()函数是阻塞式的,即程序在连接到来之前会处于挂起状态。套接字也支持非阻塞模式。

一旦接收到一个连接,accept·()函数就会返回一个单独的客户端套接字用于后续的通信。

使用新的客户端套接字就像把客户的电话转给一个客户服务人员。当一个客户打电话进来的时候,总机接了电话,然后把电话转到合适的人那里来处理客户的需求。

这样就可以空出主机,也就是最初的那个服务器套接字。

当客户端连接关闭后,服务器继续等待下一个客户端的连接。代码的最后一行会把服务器套接字关闭,由于是无限循环也许用不到。

再来创建一个TCP客户端

#创建一个TCP客户端
ss = socket()   #创建一个客户端套接字
ss.connect()    #尝试连接服务器
comm_loop:     #通信循环cs.send()/cs.recv()    #对话(接受或发送)
cs.close()         #关闭客户端套接字

在客户端有了套接字之后,马上就可以调用connect()函数去连接服务器。连接建立之后,就可以与服务器开始对话了,对话结束后,客户端就可以关闭套接字,结束连接

2.建立一个单一的连接

服务器端

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
from socket import *
cs = socket(AF_INET,SOCK_STREAM)
cs.bind(('127.0.0.1',8888))
cs.listen(5)print("Wait for......")
anne,addr = cs.accept()
print(anne)
print(addr)
anne.close()

客户端

from socket import *
cl = socket(AF_INET,SOCK_STREAM)
cl.connect(("127.0.0.1",8888))
cl.send("Hello,world".encode("utf-8"))
cl.close()

先启动服务器:

Wait for......   #accept处于等待状态

然后执行客户端,看服务器端的变化:

<socket.socket fd=384, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8888), raddr=('127.0.0.1', 54883)>
('127.0.0.1', 54883)  #客户端IP地址和端口号

上面的的代码有点单一,有多个客户端同时访问该如何?这就该用到后面的多线程,稍后会讲,这里有另外的折中代码,可以一直访问,虽然一次只能访问一个。

#服务器端
from socket import *
cs = socket(AF_INET,SOCK_STREAM)
cs.bind(("127.0.0.1",8888))
cs.listen(5)
print("Have Listen")while True:cone,addr = cs.accept()while True:data = cone.recv(1024)if len(data) == 0:break   #如果收到TCP消息,则关闭客户端套接字print(data.decode("utf-8"))cone.send(data.upper())cone.close()
cs.close()#客户端
from socket import *
cs = socket(AF_INET,SOCK_STREAM)
cs.connect(("127.0.0.1",8888))
while True:ssg = input(">>>").strip()if not ssg:continue   #避免空格造成的停顿cs.send(ssg.encode("utf-8"))  #发data = cs.recv(1024)print(data.decode("utf-8"))  #收
cs .close()

下面是在linux下的版本测试:

#服务端
#!/usr/bin/env python
#coding:utf-8from socket import *
import timeHOST = '192.168.43.131'
PORT = 8808
BUFSIZ = 1024
ADDR = (HOST,PORT)tcpser = socket(AF_INET,SOCK_STREAM)
tcpser.bind(ADDR)
tcpser.listen(5)while True:print "等待连接......"anne,addr = tcpser.accept()print "...连接:",addrwhile True:data = anne.recv(BUFSIZ)if not data:breakanne.send('[%s] %s' % (time.strftime('%c'),data))anne.close()
tcpser.close()#客户端
#!/usr/bin/env pythonfrom socket import *HOST = '192.168.43.131'
PORT = 8088
BUFSIZ = 1024
ADDR = (HOST,PORT)tcpcli = socket(AF_INET,SOCK_STREAM)
tcpcli.connect(ADDR)while True:data = input(">>>")if not data:continuetcpcli.send(data.encode("utf-8"))data = tcpcli.recv(BUFSIZ)if not data:breakprint(data.decode("utf-8"))
tcpcli.close()

四、创建UDP服务器和UDP客户端

由于UDP服务器不是面向连接的,所以不用像TCP服务器那样做那么多设置工作。

创建一个UDP服务器

#创建UDP服务器
ss = socket()  #创建一个服务器套接字
ss.bind()       #绑定服务器套接字
inf_loop:       #服务器无限循环cs = ss.recvfrom()/ss.sendto()   #对话(接收与发送)
ss.close()      #关闭服务器套接字

从伪代码中可以看出,使用的还是那套先创建套接字然后绑定到本地地址(主机/端口)的方法,无限循环中包含了从客户接受消息。

创建一个TCP服务器

#创建一个UDP服务器
cs = socket()     #创建客户端套接字
comm_loop:      #通讯循环cs.sendto()/cs.recvfrom()   #对话(发送/接收)
cs.close()   #关闭客户端套接字

创建一个真实的案例:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
#创建一个服务器
from socket import *HOST = "127.0.0.1"
PORT = 8989
BUFSIZ = 1024
ADDR = (HOST,PORT)udpser = socket(AF_INET,SOCK_DGRAM)
udpser.bind(ADDR)while True:print("等待请求......")conn,addr = udpser.recvfrom(BUFSIZ)  #接收到的消息无需转交udpser.sendto( conn.upper(),addr)   #需要的话返回一个结果就可以了print("...来自",addr)udpser.close()

UDP和TCP服务器的另一个重要的区别是,由于数据报套接字是无连接的,所以无法把客户端连接交给另外的套接字进行后续的通讯。

这些服务器只是接收消息,需要的话,给客户端返回一个结果就可以了。

#创建一个客户端服务器
from socket import *HOST = "127.0.0.1"
PORT = 8989
BUFSIZ = 1024
ADDR = (HOST,PORT)udpcli = socket(AF_INET,SOCK_DGRAM)while True:data = input(">>>")if not data:breakudpcli.sendto(data.encode("utf-8"),ADDR)data,ADDR = udpcli.recvfrom(BUFSIZ)if not data:continueprint(data.decode("utf-8"))udpcli.close()

UDP客户端的循环基本上与TCP客户端的完全一样。唯一的区别就是,我们不用先去跟UDP服务器建立连接,而是直接把消息发送出去,然后等待服务器的回复。

还可以,创建多个客户端,UDP不同于TCP需要建立连接。

#服务端
from socket import *
server = socket(AF_INET,SOCK_DGRAM)
server.bind(('127.0.0.1',9100))
while True:conn,addr = server.recvfrom(1024)print("访问来自%s,端口号是:%s" % (addr[0],addr[1]))server.sendto(conn.upper(),addr)   #返回消息的时候,必须指定端口号和ip#客户端1
from socket import *
client = socket(AF_INET,SOCK_DGRAM)
while True:data = input(">>>")   #发送空格也行,不会报错,一次发送,也不会占用资源client.sendto(data.encode("utf-8"),('127.0.0.1',9100))conn,addr = client.recvfrom(1024)print(conn.decode('utf-8'))#客户端2
from socket import *
client = socket(AF_INET,SOCK_DGRAM)
while True:data = input(">>>")client.sendto(data.encode("utf-8"),('127.0.0.1',9100))conn,addr = client.recvfrom(1024)print(conn.decode('utf-8'))

执行结果:

访问来自127.0.0.1,端口号是:60715
访问来自127.0.0.1,端口号是:60716

小结:

总的来说,UDP和TCP服务的流程相同,有两点:UDP无需提前连接直接发送消息,UDP服务器无法把客户端的连接转交出去。

这篇关于Python教程:socket()模块和套接字对象的内建方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/547602

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验