摘录 python核心编程

使用socket()模块函数创建套接字——通信端点

>>> from socket import *
>>> tcpSock = socket(AF_INET,SOCK_STREAM)
>>> udpSock = socket(AF_INET,SOCK_DGRAM)

其中,AF_INET表示使用的是IPv4协议,SOCK_STREAM表示的面向连接的TCP协议,SOCK_DGRAM表示面向无连接的UDP协议。

在创建TCP和UDP客户端与服务器前,先看看socket模块的属性以及套接字对象的方法

socket模块的属性:

属性名 描述
数据属性
AF_UNIX、AF_INET、AF_INET6、AF_NETLINK、AF_TIPC python支持的套接字地址家族
SO_STREAM、SO_DGRAM 套接字类型(TCP=流,UDP=数据报)
has_ipv6 表示是否支持IPv6的布尔标志
异常
error 套接字相关错误
herror 主机和地址相关错误
gaierror 地址相关错误
timeout 超时时间
函数
socket() 以给定的地址家族、套接字类型和协议类型(可选)创建一个套接字对象
socketpair() 以给定的地址家族、套接字类型和协议类型(可选)创建一对套接字对象
create_connection() 常规函数,它接收一个地址(主机、端口号)对,返回套接字对象
fromfd() 以一个打开的文件描述符创建一个套接字对象
ssl() 通过套接字启动一个安全套接字连接,不执行证书验证
getaddrinfo() 获取一个五元组序列形式的地址信息
getnameinfo() 给定一个套接字地址,返回二元组(主机名、端口号)
getfqdn() 返回完整的域名
gethostname() 返回当前主机名
gethostbyname() 将一个主机名映射到它的IP地址
gethostbyname_ex() gethostname()的扩展,返回主机名、别名主机集合和IP地址列表
gethostbyaddr() 将一个IP地址映射到DNS信息;返回和gethostbyname_ex()相同的三元组
getprotobyname() 将一个协议名映射到一个数字
getservbyname()/getservbyport() 将一个服务名映射到一个端口号,或者反过来;任何一个函数,协议名都是可选的
ntohl()/ntohs() 将来自网络的整数转换为主机字节顺序
htonl()/htons() 将来自主机的整数转换为网络字节顺序
inet_aton()/inet_ntoa() 将IP地址八进制字符串转换为32位包格式,或者反过来(仅用于IPv4地址)
inet_pton()/inet_ntop() 将IP地址字符串转换为打包的二进制格式,或者反过来(适用于IPv4和IPv6)
getdefaulttimeout()/setdefaulttimeout() 以秒为单位,获得/设置默认套接字超时时间

套接字对象方法和属性:

名称 描述
服务器套接字特有方法
s.bind() 将地址(主机名、端口号)绑定到套接字上
s.listen 设置并启动TCP监听器
s.accept() 被动接受TCP客户端连接,一直等到直到连接到达(阻塞)
客户端套接字特有方法
s.connect() 主动发起TCP服务器链接
s.connect_ex() connect()的扩展,此时会以错误码的形式返回问题,而不是抛出一个异常
普通的套接字方法
s.recv() 接受TCP消息
s.recv_into() 接受TCP消息到指定的缓冲区
s.send() 发送TCP消息
s.sendall() 完整的发送TCP消息
s.recvfrom() 接受UDP消息
s.recvfrom_into() 接受UDP消息到指定的缓冲区
s.sendto() 发送UDP消息
s.getpeername() 连接到套接字(TCP)的远程地址
s.getsockname() 当前套接字的地址
s.getsockopt() 返回给定套接字选项的值
s.setsockopt() 设置给定套接字选项的值
s.shutdown() 关闭连接
s.close() 关闭套接字
s.detach() 在未关闭文件描述符的情况下关闭套接字,返回文件描述符
s.ioctl() 控制套接字的模式(仅支持windows)
面向阻塞的套接字方法
s.setblocking() 设置套接字的阻塞或者非阻塞模式
s.settimeout() 设置阻塞套接字操作的超时时间
s.gettimeout() 获取阻塞套接字操作的超时时间
面像文件的套接字方法
s.fileno() 套接字的文件描述符
s.makefile() 创建于套接字关联的文件对象
数据属性
s.family 套接字家族
s.type 套接字类型
s.proto 套接字协议

创建TCP服务器

首先先来说说服务器设计的一般思路(伪代码):

ss = socket()     #1、创建服务器套接字

ss.bind()      #2、套接字于地址绑定

ss.listen()    #3、监听连接

inf_loop:     #4、服务器无限循环:  

  cs = ss.accept()    #1)接收客户端连接

  comm_loop:      #2)通信循环

    cs.recv()/cs.send()    #①对话(接收/发送)

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

ss.close()    #5、关闭服务器套接字(如有必要)

值得关心的是accept()的调用。该步骤默认会以阻塞的形式开启一个单线程服务器,用于等待客户端的连接,如果连接成功,则会返回一个独立的客户端套接字,用于和即将到来的消息进行交换,直到连接终止(终止方式一般是一方关闭连接或者向另外发送一个空字符串)。

下面的tsTserv.py脚本描述的是一个TCP服务器,接收来自客户端的消息,然后将消息加上时间戳前缀并发送给客户端:

#导入了time.time()和socket模块的所有属性
from socket import *
from time import ctime HOST = '' #空白的变量,表示可以使用任何可用的地址
PORT = 21567 #端口号
BUFSIZ = 1024 #缓冲区大小,单位是bite
ADDR = (HOST,PORT) tcpSerSock = socket(AF_INET,SOCK_STREAM) #创建一个TCP套接字
tcpSerSock.bind(ADDR) #绑定地址
tcpSerSock.listen(5) #启动TCP监听,其中5表示在连接被转接或拒绝之前,传入连接请求的最大数 while True: #服务器无限循环
print('服务器等待连接……')
tcpCliSock,addr = tcpSerSock.accept() #被动等待客户端的连接,当连接请求出现的时候,会返回一个新的套接字和客户端的地址组成的元组,于该客户端的通信是在这个新的套接字上进行数据的接受和发送s
print('……来自于:',addr) while True: #上述新套接字中进行通信循环
data = tcpCliSock.recv(BUFSIZ).decode('utf-8') #接受客户端发送过来的消息,从网络传输过来的是bytes类型的,需要解码
print(data)
if not data: #如果客户端发送的内容为空,认为客户端已经关闭,此时应该退出通信循环
break
tcpCliSock.send(('[%s] %s' % (ctime(),data)).encode('utf-8')) #服务器将处理的内容发送给客户端,需要将字符串类型数据转化为bytes数据。 tcpCliSock.close() #关闭当前客户端连接,下一步是等待另外一个客户端
tcpSerSock.close()

创建TCP客户端

下面给出创建客户端的伪代码:

cs  = socket()  #创建客户端套接字

cs.connect()    #尝试连接服务器

comm_loop:    #通信循环

  cs.send()/cs.recv()  #对话(发送/接收)

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

下面的tsTclnt.py脚本是和上面创建的服务器相关的客户端代码-连接服务器,并以逐行数据的形式提示用户,并展示从服务器返回的数据:

#导入socket模块的所有属性
from socket import * HOST = '192.168.1.125' #服务器的主机名,这里是在本地一台计算机上测试,所以这里是本地计算地址
PORT = 21567 #服务器的端口号,必须和服务端的端口号设置一样
BUFSIZ = 1024
ADDR = (HOST,PORT) tcpCliSock = socket(AF_INET,SOCK_STREAM) #创建客户端套接字
tcpCliSock.connect(ADDR) #主动调用并尝试连接服务器 while True: #无限循环
data = input('>') #等待客户端的录入
if not data: #如果用户没有输入任何的东西,则退出无限循环
break
tcpCliSock.send(data.encode('utf-8')) #将客户端的数据发送到服务器,并将字符串编码为bytes类型
data = tcpCliSock.recv(BUFSIZ).decode('utf-8') #接收服务器返回的数据
if not data: #如果服务器终止了或者上一步的recv()方法调用失败的话,也会退出无限循环
break
print(data) #正常情况下,从服务器返回的数据会被打印出来 tcpCliSock.close() #关闭客户端套接字

运行结果

首先,启动服务器

然后,在另外一台计算机(或者本机,记得更改对应的IP地址呦)上执行客户端脚本。然后就可以进行两台计算机的通信表演了。

这里要特别强调的是,我测试的版本是3.6x,通信端点发送接收内容的一定要进行编码和解码!因为,区别于2.x版本,在python3.x版本中,字符串和bytes是两种不同的数据类型了。

创建UDP服务器

和TCP服务器相比,UDP不需要那么多设置(因为他不是面向连接的),下面是伪代码:

ss = socket()  #创建服务器套接字

ss.bind()    #绑定服务器套接字

inf_loop:    #服务器无限循环

  cs = ss.recvfrom()/ss.sendto()  #关闭(接收/发送)

ss.close()    #关闭服务器套接字

上脚本:

#导入需要的模块
from socket import *
from time import ctime HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST,PORT) udpSerSock = socket(AF_INET,SOCK_DGRAM)
udpSerSock.bind(ADDR) #这里明显和TCP不同,没有所谓的‘监听传入的连接’的动作 while True:
print('等待接收消息……')
data,addr = udpSerSock.recvfrom(BUFSIZ) #接收数据报
udpSerSock.sendto(('时间:%s 地址:%s 内容:%s' % (ctime(),addr,data)).encode('utf-8'),addr) #给客户端返回数据
print('……接收并返回数据于:',addr) #服务器上打印记录信息 udpSerSock.close() #一般来说用不到,更优雅的方法是将无限循环放入一个try catch模块中,在捕捉异常或者finally中实现关闭套接字

创建UDP客户端

from socket import *

HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST,PORT) udpCliSOcket = socket(AF_INET,SOCK_DGRAM) while True:
data = input('请输入:')
if not data:
break
udpCliSOcket.sendto(data.encode('utf-8'),ADDR)
data,ADDR = udpCliSOcket.recvfrom(BUFSIZ)
if not data:
break
print(data.decode('utf-8'),ADDR) udpCliSOcket.close()

看到:UDP和TCP客户端循环的方式基本一样,唯一的区别在于,事先不需要建立与UDP服务器的连接,只是简单的发送一条消息并等待服务器的回复。

python网络编程socket编程(TCP、UDP客户端服务器)的更多相关文章

  1. 网络编程—网络基础概览、socket,TCP/UDP协议

    网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...

  2. java网络编程socket\server\TCP笔记(转)

    java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04|  分类: Socket |  标签:java  |举报|字号 订阅     1 TCP的开销 a ...

  3. 网络编程Socket之TCP之close/shutdown具体解释(续)

    接着上一篇网络编程Socket之TCP之close/shutdown具体解释 如今我们看看对于不同情况的close的返回情况和可能遇到的一些问题: 1.默认操作的close 说明:我们已经知道writ ...

  4. python基础之socket编程 (转自林海峰老师)

    python基础之socket编程   阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 ...

  5. Python 基础之socket编程(一)

    Python 基础之socket编程(一) 可以进行通信玩儿了,感觉不错不错,网络通信就像打电话,我说一句你听一句之后,你再说一句,我听一句,就这样.....下去了.不扯淡了,来来来,看看今天都搞了点 ...

  6. Python 基础之socket编程(二)

    Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...

  7. Python开发——12.socket编程

    一.OSI七层 1.物理层 物理层的主要功能是基于电气特性发送高低电压(高代表1,低代表0)形成电信号,使计算机完成组网以达到接入Internet的目的 2.数据链路层 数据链路层是用来定义电信号的分 ...

  8. Python 基础之socket编程(三)

    python 基础之socket编程(三) 前面实现的基于socket通信只能实现什么呢?在tcp协议的通信中就是一个用户说一句,服务端给你回一句,你再给服务端说一句,服务端再给你回一句,就这样一直友 ...

  9. python网络编程(Socket、TCP、UDP)

    Socket 是网络编程的一个抽象概念,通常我们用一个Socket表示 "打开了一个网络链接",而打开一个Socket 需要知道目标计算机的IP 地址和端口号,再指定协议类型即可. ...

随机推荐

  1. vue 学习 渲染、v-指令

    vue渲染 在组件中data是一个方法里面的值要是一个对象return出去 export default { name: "HelloWorld", data() { return ...

  2. 并发编程--greenlet与gevent

    什么是greenlet? 虽然CPython(标准Python)能够通过生成器来实现协程,但使用起来还并不是很方便. 与此同时,Python的一个衍生版 Stackless Python实现了原生的协 ...

  3. Spring Cloud报错Error creating bean with name 'requestMappingHandlerMapping'

    如果我们使用Spring Cloud的Feign实现熔断,首先需要自定义一个熔断类,实现你的feign接口,然后实现方法,这些方法就是熔断方法,最后需要在你的feign接口中指定fallback为自定 ...

  4. python-面向对象之封装

    封装 面向对象三大特性: 继承 封装 多态 隐藏对象的属性和实现细节,仅对外提供公共访问方法 广义上的封装 : 把方法和变量都封装在类中 狭义上的封装 : 在类的外部干脆不能调用了 优点 将变化隔离 ...

  5. 【Python还能干嘛】爬取微信好友头像完成马赛克拼图(千图成像)~

    马赛克拼图 何谓马赛克拼图(千图成像),简单来说就是将若干小图片平凑成为一张大图,如下图路飞一样,如果放大看你会发现里面都是一些海贼王里面的图片. Our Tragets 爬取所有微信好友的头像

  6. 是时候考虑让你的Spark跑在K8S上了

    [摘要] Spark社区在2.3版本开始,已经可以很好的支持跑着Kubernetes上了.这样对于统一资源池,提高整体资源利用率,降低运维成本(特别是技术栈归一)有着非常大的帮助.这些趋势是一个大数据 ...

  7. 侠梦说pinpoint--界面上的图标之AgetnInfo数据研究

    前言 在启动一个挂载pinpoint的springboot项目的时候,界面上显示成了jboss的图标,所以今天研究了一下这个数据是怎么来的. 我们知道不同图标和服务类型有关,服务不同,图标就不同,这在 ...

  8. Redis KeyExpire的使用

    Set a timeout on key. After the timeout has expired, the key will automatically be deleted. A key wi ...

  9. css分类和选择器

    css的分类:内联,内嵌,外部 内联:写在标签里,style=样式,控制精准代码实用性差. 内嵌:嵌在<head></head>里 <style type="t ...

  10. Python3 函数进阶2

    目录 迭代器 可迭代对象 迭代器对象 总结和补充 列表推导式 字典生成式 zip()函数 递归 迭代器 迭代器是访问容器类数据类型元素的一种方式 迭代器是一个可以记住遍历的位置的对象 迭代器对象从容器 ...