python网络通信框架_Python C/S架构,网络通信相关名词,socket编程

主要内容:

一. C/S架构

二. 网络通信的相关名词

三. socket编程

一. C/S架构和B\S架构概述

1. C/S架构: Client/Server(客户端/服务端)架构

描述: C/S架构--需要服务端部署;用户单独安装客户端,客户端软件升级,服务端要为每个用户服务.可以不联网使用.

客户端(client): 享受服务端提供的服务

服务端(server): 给客户端提供服务

硬件C/S架构: 打印机

软件C/S架构: 聊天软件(如:QQ,微信),视频软件(如:优酷视频,暴风影音)

2. B\S架构: Browser/Server(浏览器/服务器)架构

描述: 需要服务端部署;浏览器访问;服务端负责全部逻辑;升级方便;必须联网使用.

CS/BS本质相同,都是客户端与服务端通信,只是表现为不同的形式,BS架构的软件客户端固定是浏览器.

二. 网络通信的相关名词

1. 集线器(HUB): HUB是一个多端口的转发器.主要功能是对接收到的信号进行再生整形放大,以扩大网络的传输距离,同时把所有节点集中在以它为中心的节点上.将咱们所有的插上集线器的电脑连通起来.

2. 交换机(Switch): 升级版集线器.它可以为接入交换机的任意两个网络节点提供独享的电信号通路.

3. 网卡: 作用是接收电信号,有网络接口(用于插网线)

网卡是局域网中连接计算机和传输介质的接口,能实现与局域网传输介质之间的物理连接和电信号匹配.

4. MAC地址(物理地址): MAC地址又称为物理地址,硬件地址,用来定义网络设备的位置.

MAC地址是网卡决定的,固定的,全球唯一的,相当于每台电脑的上网身份证.

物理地址: ‎20-47-47-68-EE-DF --> 16进制的6个数表示,前三位厂商编号,后三位生产流水号

5. 多播\单播: 多播指一点对多点的通信,在IPv6中把广播看作是多播的一个特殊例子. 单播指客户端与服务器之间的点到点连接.

6. 广播风暴: 缺点是 -->不安全,容易拥堵网络.

7. IP地址: 英文是Internet Protocol Address, 指互联网协议地址. IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异.

作用: 划分广播域

分类:

IPv4: 4个点份十进制 (目前使用较多)

IPv6: 6个冒号分十六进制

8. DHCP协议: 两个作用

(1)给内部网络或网络服务供应商自动分配IP地址.

(2)给用户或者内部网络管理员作为对所有计算机作中央管理的手段.

9. 子网掩码: 计算是否属于同一网段,属于同一网段的,我们称为属于同一子网.

子网掩码不能单独存在,它必须结合IP地址一起使用.子网掩码只有一个作用,就是将某个IP地址划分成网络地址和主机地址两部分.

10. DNS服务器: 具有域名解析的作用,即把域名解析为IP地址. 默认跟着网关走. 记录着所有的域名和它网站对应的那台服务器的IP地址的对应关系,理解为一个字典.

11. 路由器: 是连接因特网中各局域网,广域网的设备,它会根据信道的情况自动选择和设定路由,以最优路径,按前后顺序发送信号.

12. 路由协议: 用于确定到达路径,计算最优路径.

13. 网关: 是一个网络连接到另一个网络的"关口",也就是网络关卡. 它是公网IP,也可以说是路由器的IP地址.

14. NAT技术: 网络地址转换,将局域网的IP地址转换为公网(网关)的IP地址

15. 局域网: 也称内网

16. 端口:标识电脑上某个应用程序. 通过IP地址+端口-->我们就能唯一确定一台电脑上的某个应用程序.

如果把IP地址比作一间房子,端口就是出入这间房子的门.真正的房子只有几个门,但是一个IP地址的端口可以有65536(即:2^16)个之多!

端口是通过端口号来标记的,端口号只有整数,范围是从 0 到 65535(2^16-1). 其中0-1024是电脑内部服务使用的,不要去占用. 一般来说,自己编程时不去占用8000以内的数值.

17. 端口映射: 访问网站时自动携带一个端口号,用于直接访问服务端.

三. socket(这里是

1. 概述:

socket通常也承做"套接字", 用于描述IP地址和端口, 是一个通信链的句柄, 应用程序通常通过"套接字"向网络发出请求或者应答网络请求.

socket起源于Unix, 而Unix/Linux基本哲学之一就是"一切皆文件", 对于文件用[打开][读写][关闭]模式来操作. socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO,打开,关闭)

2. socket和file的区别:

file模块是针对某个指定文件进行[打开][读写][关闭]

socket模块是针对 服务器端 和 客户端Socket进行[打开][读写][关闭]

3. 套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的:

(1)基于文件类型的套接字家族

套接字家族的名字: AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信

(2)基于网络类型的套接字家族

套接字家族的名字: AF_INET

(还有AF_INET6被用于ipv6,还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,或者是很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我们只使用AF_INET)

4. TCP与UDP区别(很重要!!)

tcp协议:面向连接,消息可靠,相对udp来讲,传输速度慢,消息是面向流的,无消息保护边界(0).

udp协议:面向无连接,消息不可靠,传输速度快,消息是面向包的,有消息保护边界.

5. TCP协议下端口重用问题

当socket绑定IP地址和端口时可能出现以下异常:

OSError: [Errno 48] Address already in use

我们可以采用端口重用的方法解决这个问题:

ContractedBlock.gif

ExpandedBlockStart.gif

#加入一条socket配置,重用ip和端口,代码如下:

importsocketfrom socket importSOL_SOCKET,SO_REUSEADDR

sk=socket.socket()

sk.setsockopt(SOL_SOCKET, SO_REUSEADDR,1) #在bind前加上这一行代码,表示允许地址重用

sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字

sk.listen() #监听链接

conn,addr = sk.accept() #接受客户端链接

ret = conn.recv(1024) #接收客户端信息

print(ret) #打印客户端信息

conn.send(b'hi') #向客户端发送信息

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

sk.close() #关闭服务器套接字(可选)

端口重用

但是如果加上了上面的代码之后还是出现了这样的异常:

OSError: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试

那么意味着你的电脑不支持端口重用,只能更换端口了.

6. TCP和UDP下socket差异对比图:

1464512-20181017162748983-1457903205.png

7. TCP协议下socket的通讯流程:

服务端(server)相关操作:

#引入socket模块

importsocket#创建服务端对象

surver_obj =socket.socket()#设置服务端IP和端口号

ip_port = ("IP地址", 端口号)#绑定IP和端口

surver_obj.bind(ip_port)#监听客户端对象(侦听客户端请求)

surver_obj.listen()#accept()方法使服务端对象接受连接,并返回元组(conn, address)

conn, address =surver_obj.accept()#recv(bufsize)方法接受套接字对象的数据.数据以bytes字符串形式返回

from_client_msg = conn.recv(1024)#把bytes字符串解码成为utf-8格式的字符串

from_client_msg = from_client_msg.decode("utf-8")#服务端通过套接字对象conn给客户端发送信息(send内部必须是bytes格式的字符串)

conn.send("要发送的内容".encode("utf-8"))#关闭新的套接字对象(理解为连接通道)

conn.close()#关闭服务端对象

surver_obj.close()

客户端(client)相关操作:

#引入socket模块

importsocket#创建客户端对象

client_obj =socket.socket()#拿到服务端的IP地址和端口

surver_ip_port = ("IP地址", 端口号)#客户端对象通过 服务端的IP地址和端口 与服务端建立连接

client_obj.connect(surver_ip_port)#客户端对象向服务端发送信息

client_obj.send("要发送的内容".encode("utf-8"))#接收套接字对象的数据,数据以字符串的形式返回,指定每次最多可接收的数据数量是 1024 Bytes

from_surver_msg = client_obj.recv(1024)#把接收到的bytes字符串转换成utf-8格式的字符串

from_surver_msg = from_surver_msg.decode("utf-8")#关闭客户端对象

client_obj.close()

8. UDP协议下socket的通讯流程:

服务端:

importsocket#创建一个UDP协议下的服务端对象,需要使用参数type=socket.SOCK_DGRAM

udp_server = socket.socket(type=socket.SOCK_DGRAM)#服务端拿到自己的IP地址,并给本程序分配端口号

ip_port = ("192.168.15.28", 11111)#绑定IP地址和端口

udp_surver.bind(ip_port)#服务端接收信息

from_client_msg, client_address = udp_surver.recvfrom(1024)#服务端发送信息

udp_surver.sendto("服务端想要发送的内容".encode("utf-8"), client_address)#关闭服务端

udp_surver.close()

客户端:

importsocket#创建一个UDP协议下的客户端对象,需要使用参数type=socket.SOCK_DGRAM

udp_client = socket.socket(type=socket.SOCK_DGRAM)#拿到服务端的IP地址和程序端口

surver_ip_port = ("192.168.15.28", 11111)#客户端发送信息

udp_client.sendto("客户端想要发送的内容".encode("utf-8"), surver_ip_port)#客户端接收信息

from_surver_msg, surver_address = udp_client.recvfrom(1024)#关闭客户端

udp_client.close()

9. 以上代码涉及到的方法的解释

(1) obj = socket.socket(family, type, proto)

描述: 创建socket对象

参数:

family(地址族):

socket.AF_INET --> IPv4(默认)

socket.AF_INET6 --> IPv6

type(类型):

socket.SOCK_STREAM --> 面向连接(TCP协议)

socket.SOCK_DGRAM --> 面向不连接(UDP协议)

protocol(协议):

该参数一般不填,默认为0.

(默认)与特定的地址家族相关的协议,如果是0,则系统就会根据地址格式和套接类别,自动选择一个合适的协议.

(2) obj.bind(address)

描述: 将套接字绑定到地址

参数: address地址的格式取决于地址族. 例如,在AF_INET下,以元组(IP地址, 端口号)的形式表示地址

(3) obj.listen(backlog)

描述: 侦听客户端请求

参数: backlog指定在拒绝连接之前,可以挂起的最大连接数量.不写则默认为无限制(一般不写).

(4) conn, address = obj.accept()

描述: 接受连接并返回元组(conn, address), 其中conn是新的套接字对象,可以用来接收和发送数据(可以把conn理解为一个通信管道). address是连接客户端的地址(元组).

(5) obj.connect(address)

描述: 连接到address处的套接字.

参数: 一般address的格式为元组(IP地址, 端口号),如果连接出错,返回socket.error错误.

(6) obj.close()

描述: 关闭套接字

(7) obj.recv(bufsize, flags)

描述: 接受套接字的数据,数据以bytes字符串的形式返回.

参数:

bufsize --> 指定最多可接收的数据量,单位B(bytes)

flags --> flag提供有关消息的其他信息,通常可以忽略.

(8) obj.recvfrom(bufsize, flags)

描述: 与recv()类似,但返回值是(data,address).其中data是包含接收数据的字符串,address是发送数据的套接字地址(元组).该函数主要用于UDP协议.

注意:recvfrom()方法返回客户端数据(bytes字符串格式)和客户端地址,其中客户端地址address是一个元组,内部包括客户端IP地址和客户端程序端口号.

(9) obj.send(data, flags)

描述: 将data中的数据发送到连接的套接字.返回值是要发送的字节数量,该数量可能小于data的字节大小.

(10) obj.sendto(data, address)

描述: 将数据发送到套接字,address是形式为(IP地址,端口号)的元组.指定远程地址.返回值是发送的字节数.该函数主要用于UDP协议.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值