python网络编程socket编程(TCP、UDP客户端服务器)
摘录 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客户端服务器)的更多相关文章
- 网络编程—网络基础概览、socket,TCP/UDP协议
网络基础概览 socket概览 socket模块—TCP/UDP的实现 TCP/UDP总结 网络基础概览 osi七层协议各层主要的协议 # 物理层传输电信号1010101010 # 数据链路层,以太网 ...
- java网络编程socket\server\TCP笔记(转)
java网络编程socket\server\TCP笔记(转) 2012-12-14 08:30:04| 分类: Socket | 标签:java |举报|字号 订阅 1 TCP的开销 a ...
- 网络编程Socket之TCP之close/shutdown具体解释(续)
接着上一篇网络编程Socket之TCP之close/shutdown具体解释 如今我们看看对于不同情况的close的返回情况和可能遇到的一些问题: 1.默认操作的close 说明:我们已经知道writ ...
- python基础之socket编程 (转自林海峰老师)
python基础之socket编程 阅读目录 一 客户端/服务器架构 二 osi七层 三 socket层 四 socket是什么 五 套接字发展史及分类 六 套接字工作流程 七 基于TCP的套接字 ...
- Python 基础之socket编程(一)
Python 基础之socket编程(一) 可以进行通信玩儿了,感觉不错不错,网络通信就像打电话,我说一句你听一句之后,你再说一句,我听一句,就这样.....下去了.不扯淡了,来来来,看看今天都搞了点 ...
- Python 基础之socket编程(二)
Python 基础之socket编程(二) 昨天只是对socket编程做了简单的介绍,只是把socket通信的框架搭建起来,要对其中的功能进行进一步的扩充,就来看看今天的料哈! 一.基于tcp的套接字 ...
- Python开发——12.socket编程
一.OSI七层 1.物理层 物理层的主要功能是基于电气特性发送高低电压(高代表1,低代表0)形成电信号,使计算机完成组网以达到接入Internet的目的 2.数据链路层 数据链路层是用来定义电信号的分 ...
- Python 基础之socket编程(三)
python 基础之socket编程(三) 前面实现的基于socket通信只能实现什么呢?在tcp协议的通信中就是一个用户说一句,服务端给你回一句,你再给服务端说一句,服务端再给你回一句,就这样一直友 ...
- python网络编程(Socket、TCP、UDP)
Socket 是网络编程的一个抽象概念,通常我们用一个Socket表示 "打开了一个网络链接",而打开一个Socket 需要知道目标计算机的IP 地址和端口号,再指定协议类型即可. ...
随机推荐
- iOS开发调试概览
概述 我们都知道Xcode默认的调试器是LLDB(在此之前使用的是GDB),但是关于LLDB的debug技巧并非所有人都比较清楚,可能所有人都知道p或者po命令打印一些变量.但是实际的情况时这些还远远 ...
- jvm垃圾回收器与内存分配策略
一.判断对象存活的算法 1.引用计数算法 (1)概念:给对象中添加一个引用计数器每当有一个地方引用它时,计数器值加1:当引用失效时,计数器就减1:任何时刻计数器为0的对象就是不可能再被使用的. (2) ...
- shell脚本exercise2
通过文件里面的网址,判断是否访问成功网址 #!/bin/bash check(){ code=`curl -I -m -o /dev/null -s -w %{http_code} http://$u ...
- request获取路径
1.request.getRequestURL() 返回的是完整的url,包括Http协议,端口号,servlet名字和映射路径,但它不包含请求参数. 2.request.getRequestURI( ...
- 洛谷 P2388 阶乘之乘 题解
本蒟蒻又来发题解了QwQ; 看到这个题目,本蒟蒻第一眼就想写打个暴力: 嗯,坏习惯: 但是,动动脑子想一想就知道,普通的的暴力是过不了的: 但是,身为蒟蒻的我,也想不出什么高级的数学方法来优化: 好, ...
- HashMap踩坑实录——谁动了我的奶酪
说到HashMap,hashCode 和 equals ,想必绝大多数人都不会陌生,然而你真的了解这它们的机制么?本文将通过一个简单的Demo还原我自己前不久在 HashMap 上导致的线上问题,看看 ...
- cesium 实现 3d-tiles 平移旋转贴地(附源码下载)
前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...
- FIve in a row
Alice and Bob play 5-in-a-row game. They have a playing field of size 10 × 10. In turns they put eit ...
- HDU 5121 Just A Mistake
Just A Mistake Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) ...
- CodeForces-617E XOR And Favorite Numbers(莫队)
Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is g ...