文章目录

  • 网络基础
    • 网络协议
    • IP地址与端口
    • socket套接字
      • 概念
      • Python中socket模块
  • TCP下的服务器与客户端
    • TCP工作原理
    • TCP服务器的实现
    • TCP客户端的实现
  • UDP下的服务器与客户端
    • UDP工作原理
    • UDP服务器的实现
    • UDP客户端的实现

网络基础

网络协议


网络协议是计算机网络数据进行彼此交换而建立起的规则或标准。就像我们说的普通话一样,网络协议是计算机设备间的“普通话”,是一种彼此交流的方式。更多计算机网络总结可参考这篇博客,此处不便赘述。

不得不提网络协议三要素:语义、语法、同步

  • 语义:即需要发出何种控制信息,完成何种动作以及做出何种相应,“讲什么”。
  • 语法:即数据与控制信息的结构或格式,“怎么讲”。
  • 同步:即事件实现顺序的详细说明。

在著名的OSI/RM模型中,将网络协议划分为7层,如下图所示:

网络协议中最为重要的是TCP/IP协议,它是互联网的基础协议。TCP/IP协议并不是TCP和IP协议的合称,是因特网整个网络TCP/IP协议簇。协议体系结构如图中四个层次,包括网络接口层、网络层、传输层、应用层。

IP地址与端口


IP(Internet Protocol)是计算机网络相互连接进行通信而设计的协议,位于TCP/IP协议簇体系网络层中。它规定了计算机在因特网上进行通信时应当遵守的规则,是所有计算机网络实现通信的一套规则。换句话说,任何计算机系统只要遵守IP协议就可以与因特网互联互通。

每一台主机都有一个唯一的IP地址,IP协议正是利用IP地址在主机间传递信息。IP地址由网络标识号码与主机标识号码两部分组成,可以分为ABCDE五类,分别适用大型网络、中型网络、小型网络、多目地址、备用。可以在cmd输入ipconfig查看信息。

IP地址不便于记忆,通常会使用主机名来代替IP地址,即使用DNS域名解析协议。比如输入“baidu.com”就能访问到百度了,不必输百度的IP地址。

端口是计算机与外界进行通信交流的出口,我们通过IP或域名访问到一台具体的计算机后,可以通过端口号来访问这台计算机上对应的软件或服务。常用的保留TCP端口号有HTTP80、FTP20/21、Telnet23、SMTP25、DNS53等。
更多细节可参考这篇博客,此处不便赘述

socket套接字

概念


socket是网络通信端口的一种现象,也称套接字。用于描述IP地址和端口,是一个通信链的句柄,以实现不同计算机间的通信,可以比喻成一个多孔插座,不同型号的插座得到不同的服务。具体来说就是两个程序通过一个双向通信连接实现数据的交换,而这个连接的一段就是一个socket。

socket是应用层与TCP/IP协议簇通信的中间软件抽象层,是应用层与运输层间的桥梁,如下图所示:

Python中socket模块


一、socket模块中的socket类
Python中,可以通过socket模块实现网络通信,该模块提供了一个scoket类,定义如下:

class socket(_socket.socket):def __init__(self,family=AF_INET,type=SOCK_STREAM,proto=0)

从上述定义看出,socket类是_socket.socket子类,根据给定的地址簇、套接字类型和协议号创建一个新的socket。套接字是通过地址簇套接字类型两个主要属性来控制如何发送数据。如下:

  • family套接字地址簇
    可取值有AF_INET(默认,用于IPv4寻址)、AF_INIET6(用于IPv6寻址)、AF_UNIX(UNIX域套接字的地址簇,仅支持UDS系统)等等。一般默认值是最高效的。
  • type套接字类型
    默认SOCK_STREAM,还可取SOCK_DGRAMSOCK_RAW等。SOCK_STREAM对应传输控制协议TCP。 TCP确保每条信息按顺序正确发送,而UDP传送没有顺序,可能多次传送或不传送,适合广播。
  • proto协议编号
    通常为0,可以忽略

由socket类创建的socket对象有一系列方法及属性,篇幅限制(偷懒 )不再一一演示,梳理如下(建议收藏):

名称 描述
服务器套接字方法
sock.bind() 将地址绑定到套接字上
sock.listen() 设置并启动TCP监听器
sock.accept() 被动接收TCP客户端连接,一直阻塞直到连接到达
客户端套接字方法
sock.connect() 发起TCP客户端连接
sock.connect_ex() connect()扩展版本,会以错误码形式显示异常
普通的套接字方法
sock.recv() 接收TCP消息
sock.recv_into() 接收TCP消息到指定缓冲区
sock.send() 发送TCP消息
sock.sendall() 完整发送TCP消息
sock.recvfrom() 接收UDP消息
sock.recvfrom_into() 接收UDP消息到指定的缓冲区
sock.sendto() 发送UDP消息
sock.getpeername() 连接到套接字的远程地址
sock.getsockname() 获取当前套接字地址
sock.getsockopt() 获取给定套接字选项的值
sock.shutdown() 关闭连接
sock.share() 复制套接字并准备与目标进程共享
sock.close() 关闭套接字
sock.detach() 在未关闭文件描述符的情况下关闭套接字并返回文件描述符
sock.ioctl() 控制套接字的模式
面向阻塞的套接字方法
sock.setblocking() 设置套接字的阻塞或非阻塞模式
sock.gettimeout() 获取阻塞套接字操作的超时时间
面向文件的套接字方法
sock.fileno() 套接字的文件描述符
sock.makefile() 创建与套接字关联的文件对象
数据属性
sock.family() 套接字家族
sock.type() 套接字类型
sock.proto() 套接字协议

二、socket模块中其他功能函数

小结如下(建议码住):

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

几个常用举例:

import socket
print('-----将主机端口转换为五元组(family,type,proto,canonname,sockaddr):')
print(socket.getaddrinfo('baidu.com',port=80))
print(socket.getaddrinfo('example.org',80,proto=socket.IPPROTO_TCP))
print('-----当前主机名')
print(socket.gethostname())
print('-----返回限制域名:')
print(socket.getfqdn())  #不带参默认本机
print(socket.getfqdn('baidu.com'))  #可能网络影响有点慢
print(socket.getfqdn('123.110.50.216'))
print('-----主机名转换IP地址')
print(socket.gethostbyname('baidu.com'))
print(socket.gethostbyname('123.125.105.110'))
print('-----主机名转换IP地址并返回三元组(hostname,aliaslist,ipaddrlist)')
print(socket.gethostbyname_ex('baidu.com'))

(插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

TCP下的服务器与客户端


TCP(Transmission Control Protocol)传输控制协议是一种面向连接的、可靠的和基于字节流的传输层通信协议,用于在不可靠的互联网络上提供可靠的、端对端字节流传输服务。

位于TCP/IP体系结构的传输层是处在IP层之上、应用层之下的中间层,所以数据传输必须经过IP层。当应用层想TCP层发送用于网间传输、用八位字节表示的数据流时,TCP把数据流分割成适当长度的报文段,然后把离散的报文组装为比特流。为了保障数据的可靠传输,会对从应用层传送到TCP实体的数据进行监管,并提供了重发机制和流控制。

TCP工作原理


TCP是如何保障数据可靠不丢失且有序呢?答案是对传输数据按字节进行了编号,编号的目的是保证传送到接收端的数据能够按顺序接收。接收端会对已经接收的数据发回一个确认,若发送端在规定时间内未收到有编号的数据,则将重新传送前面的数据。

如何编号?TCP不是使用顺序的整数作为数据包的编号,而是通过一个计数器记录发送的字节数,且TCP初始序列号是随机选择的,这样可以避免TCP序号易于猜测而伪造数据进行欺骗或攻击。比如包大小是2048字节,初始序号为3000,那么下一个数据包的序号是5048。

此外,TCP可以一次性发送多个数据包,无须按数据包依次发送。同时可以通过发送方传输的数据量大小来进行减缓或暂停(流量控制),若发送数据包丢弃,就会减少每秒发送的数据量。

结合前面讲的socket模块,要如何进行TCP通信呢?先从服务器开始:初始化Socket、然后绑定(bind)端口、监听(listen)端口、调用accept阻塞、最后等待客户端连接;某个客户端初始化一个Socket,然后连接(connect)服务器。若连接成功,那么客户端与服务器的连接就建立了,客户端发送数据请求,服务器接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互就结束了。上图解:

TCP服务器的实现


创建TcpServer.py,使用socket模块实现TCP服务器,启动服务器,等待客户端连接,详见注释:

import socketHOST = 'localhost'  # 主机
PORT = 6666   # 端口
BUF_SIZE = 1024  # 最大字节数
ADDRESS = (HOST, PORT)  # 地址(IP,端口)if __name__ == '__main__':# 新建socket连接server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 将套接字与指定IP端口连接server_socket.bind(ADDRESS)# 启动监听(并设最大连接数为5)server_socket.listen(5)print('正在监听:%s:%d' % (HOST, PORT))while True:print(u'服务器已就绪,等待连接中...')# 当有连接时,把收到的套接字存到client_sock,远程连接细节存到address中client_sock, address = server_socket.accept()print(u'连接客户端地址:',address)while True:# 接收数据data = client_sock.recv(BUF_SIZE)if not data or data == 0:breakprint('来自客户端信息:%s' % data.decode('utf-8'))# 发送数据client_sock.send('好的'.encode('utf-8'))client_sock.close()  # 关闭客户端server_socket.close()  # 关闭socket

运行服务器:

TCP客户端的实现


新建TcpClient.py:

import socketHOST = 'localhost'
PORT = 6666  # 注意端口一致
BUF_SIZE = 1024
ADDRESS = (HOST, PORT)if __name__ == '__main__':# 创建socketsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 连接服务器sock.connect(ADDRESS)print('成功连接目标主机:%s,目标主机端口:%s' % (HOST,PORT))# 发送数据sock.send('记得一键三连~'.encode('utf-8'))# 接收数据msg=sock.recv(BUF_SIZE)print('来自服务器信息:%s' % msg.decode('utf-8'))#关闭连接sock.close()

运行客户端:

服务器结果:

注意发送接收数据时以bytes进行而不是string,要不然会报错“TypeError: a bytes-like object is required, not ‘str’”,所以使用encode()decode()进行编码和解码。

UDP下的服务器与客户端


UDP(User Datagram Protocol)用户数据报协议是OSI模型中一种无连接的传输层协议,提供了面向事务的简单不可靠消息传送服务。

UDP同TCP一样也是用于处理数据包,不过它只负责将应用层的数据发送出去,不具备差错控制和流量控制。因此在传送过程中如果数据出错就要由高层协议处理,但也因为没有差错控制和流量控制的开销,所以使得传输效率高、延时小,适用于对可靠性要求不高的应用,可以快速大量的发送数据但不负责可靠性,同文章开头表情包,快不快就完事了 。

UDP工作原理


UDP提供不可靠的无连接数据包传输服务,使用底层互联网协议传送报文,IP报文协议号是17,其报文是封装在IP数据报中进行传输的。UDP报文由UDP源端口自动、UDP目标端口字段、UDP报文长度字段、UDP校验和字段以及数据区组成。首先通过端口机制进行复用和分解,每个UDP应用程序在发送数据报文之前,必须与操作系统协商获取相应的协议端口及端口号,然后根据目的端口号进行分解,接收端使用UDP的校验进行确认,查看UDP报文是否正确到达了目标主机的相应端口。

UDP服务器的实现


新建UdpServer.py:

import socket
BUF_SIZE = 1024if __name__ == '__main__':# 新建socket连接(用SOCK_DGRAM即UDP=数据报)sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 绑定主机和端口sock.bind(('localhost',8888))while True:print(u'服务器已就绪,等待连接中...')# 当也有连接时,将接收数据存到data,远程连接细节存到addressdata, address = sock.recvfrom(BUF_SIZE)print('连接客户端地址:', address)print('来自客户端信息:%s' % data.decode('utf-8'))# 发送数据sock.sendto('收到'.encode('utf-8'),address)

运行服务器:

UDP客户端的实现


新建UdpClient.py:

import socket
BUF_SIZE = 1024if __name__ == '__main__':# 新建socket连接sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)# 发送数据sock.sendto('在线蹲个一键三连~'.encode(), ('localhost', 8888))# 接收数据data, address = sock.recvfrom(BUF_SIZE)print('连接服务器地址:', address)print('来自服务器信息:%s' % data.decode())

运行客户端:

服务器结果:

注意UDP与TCP连接不同的是socket.socket()的第二个参数。TCP使用SOCK_STREAM,UDP使用SOCK_DGRAM

Python系列博客持续更新中

原创不易,请勿转载(本不富裕的访问量雪上加霜 )
博主首页:https://wzlodq.blog.csdn.net/
微信公众号:吾仄lo咚锵
如果文章对你有帮助,记得一键三连❤

Python网络编程-一文厘清socket、TCP和UDP那点事相关推荐

  1. python 网络编程 计算机部分基础 和初识tcp和udp

    架构 ---- 程序员开发的一种模式 C/S 架构  客户端/服务器模式 B/S架构  Browser浏览器/服务器模式 B/S架构的优势:统一了应用的接口 软件开发的架构 我们了解的涉及到两个程序之 ...

  2. python网络编程需要学什么,python网络编程学习笔记(五):socket的一些补充 Python 网络编程需要学习哪些网络相关的知识...

    python的socket编程问题hdr = recvall(s, 5) if hdr is None: print 'Unexpected EOF receivingstruct在unpack的时候 ...

  3. python php 全双工,Python网络编程之使用select实现socket全双工异步通信功能

    这篇文章主要介绍了Python网络编程使用select实现socket全双工异步通信功能,在这里分享给大家,有需要的朋友可以参考下 本文实例讲述了Python网络编程使用select实现socket全 ...

  4. 网络编程之 传输层的协议TCP与UDP

    传输层协议: TCP和UDP的区别: TCP:面向连接(经历三次握手).传输可靠(保证数据正确性,保证数据顺序).用于传输大量数据(流模式).速度慢,建立连接需要开销较多(时间,系统资源). 服务端和 ...

  5. 网络编程(part8)--传输层服务之TCP和UDP

    鄙人学习笔记 文章目录 传输层服务 面向连接的传输服务(基于TCP协议的数据传输) 传输特征 实现手段 适用情况 面向无连接的传输服务(基于UDP协议的数据传输) 传输特点 适用情况 传输层服务 面向 ...

  6. 真良心干货保姆级手把手教你Python网络编程,学不会我去你家教你

    Python网络编程 基本概念(计算机网络基础) IP地址与端口 IP地址 端口 网络通信协议 网络通信协议 网络协议的分层 TCP/UDP 套接字编程 socket()函数介绍 UDP 编程 实现U ...

  7. python网络编程难点_python之路网络编程总结(三)

    2018-9-22 20:58:25 1. 端口 1.1知名端口是众所周知的端口,范围从0-1023 例: 80端口分配给HTTP服务 21 端口分配给FTP服务 1.2动态端口 : 范围从1024 ...

  8. python网络编程--socket简单实现

    python网络编程                                                                                           ...

  9. Python 网络编程(Socket)

    Python 网络编程(Socket) 一.Socket 套接字 1.Socket 编程 socket本质是编程接口(API),对TCP/IP的封装,提供可供程序员做网络开发所用的接口.Socket ...

最新文章

  1. 什么是优秀管理者的第一课?【如何搞垮一个企业】
  2. 写python程序用什么软件最好-Python必学之编译器用哪个好?你用错了吧!
  3. 文件服务器传输,文件服务器传输
  4. mysql级联查询_mysql 各种级联查询后更新(update select)
  5. ACL 2018 收录论文 | 如何高效提炼有效信息?
  6. 程序猿生存指南-38 枯木逢春
  7. ui automator viewer 怎么获取界面名_ui交互设计怎么样
  8. [HttpException (0x80004005): Failed to Execute URL.]之画蛇添足之痛
  9. 浅谈Object Pascal的指针[引用 Nicrosoft]
  10. 第三方开源 jar 包推荐
  11. PermutationsUnique,求全排列,去重
  12. python能做什么游戏-有趣又好玩的9个Python编程小游戏、简直太棒了
  13. e.style.opacity 通过javascript调用元素的样式属性
  14. 电阻器颜色代码在线计算机,色环电阻计算器
  15. 一、TI毫米波雷达系列——硬件加速器(HWA)
  16. 俺的web课设大作业
  17. Linux刻录固态硬盘教程,linux迁移至固态硬盘全过程
  18. [ kvm ] 学习笔记 1:Linux 操作系统及虚拟化
  19. HTML canvas 输入文字,关于Canvas写字
  20. 仿热血江湖帮战客方血帮战 开始对战记时器结束事件

热门文章

  1. 安科瑞变电站综合自动化系统在安庆市静脉产业园应用
  2. 数码管显示原理:共阴极和共阳极的区别,静态显示程序。
  3. vue 后台获取路由表,addRouters动态路由
  4. addRoutes的基本使用
  5. 关于“茴香豆的‘茴’有几种写法”:学习过程中,若时间精力有限则优先记住最好用的一种
  6. 如何构建一个大脑---为工程师们介绍神经生理学.
  7. 气瓶安全云充装V1.0.201604
  8. opencv 照片动漫风格
  9. 台湾清华大学计算机网络--003 WLAN
  10. 揭秘程序员面试潜规则,你知道几条(建议收藏)!