十一、网络编程

一、网络编程的目标

编写一个C/S或B/S架构的基于网络通信的软件

C/S架构:客户端---服务端
B/S架构:浏览器----服务端

学习socket编程就是要编写客户端软件和服务端软件,然后实现服务端和客户端基于网络通信

服务端特点:1、不间断地提供服务;2、服务端要支持并发+高性能

二、网络

网络 = 物理连接介质 + 互联网协议

互联网协议分为OSI七层,或TCP/IP五层:

物理层:发送电信号-----基于二进制

数据链路层:ethernet以太网协议-----基于mac地址,在局域网内通信

网络层:IP协议-----基于IP地址

传输层:TCP/UDP协议------基于端口(端口即应用程序与网卡关联的编号)

应用层:HTTP、mail、ftp协议等

IP协议的作用:一个是为每一台计算机分配IP地址,另一个是确定哪些地址在同一个子网络

ARP协议:在同一个局域网内,根据IP地址获取mac地址,操作系统自动转换

路由协议:网关与网关之间的通信

TCP协议:TCP建立的是一个双向连接,也叫流式协议

                  3次握手,建立客户端和服务端的双向通路

                  4次挥手,断连接,服务端先发起断连

mac地址 + IP地址 +端口就可以定位到世界上独一无二的应用软件;有了ARP协议,IP地址 + 端口就可以定位到世界上独一无二的应用软件

三、socket编程

sockct(套接字)是位于应用层和传输层之间的一个抽象层,专门把传输层以下的协议封装成接口给应用层使用。

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

套接字家族的名字:AF_UNIX
套接字家族的名字:AF_INET

1、socket工作流程

服务端:
socket()---bind()---listen()---accept()---recv()---send()---close()

 服务端先初始化socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。

服务端:

socket()---connect()---send()---recv()---close()

客户端初始化一个socket,然后连接服务器(connect),如果连接成功,这时客户端与服务端的连接就建立了。

客户端发送数据请求(send),服务器端接收请求并处理请求(recv),然后把回应数据发送给客户端(send),客户端读取数据(recv),最后关闭连接(close),一次交互结束。

bind()     绑定IP地址和端口。本地回环地址:127.0.0.1,端口:0到65535,其中0到1024是给系统用的
listen()     括号里面的数字代表同一时间只能进来多少个请求
accept()     等待信息
reav(1024)     代表收消息,1024是一个最大的限制
send()     回消息
close()     关闭连接

2、粘包

只有TCP有粘包现象,UDP永远不会粘包,因为TCP协议是面向流的协议,而UDP是面向消息的协议。
所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的

两种情况下会发生粘包:
1、发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小,会合到一起,产生粘包)
2、接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)

TCP是基于数据流的,于是收发的消息不能为空,这就需要在客户端和服务端都添加空消息的处理机制

粘包的解决方法:
为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据

使用struct模块解决粘包

struct模块的作用:
1、把整型数字转成bytes类型
2、转成的bytes是固定长度

可以把报头做成字典,字典里包含将要发送的真实数据的详细信息,然后json序列化,然后用struck将序列化后的数据长度打包成4个字节(4个自己足够用了)

发送时:
先发报头长度
再编码报头内容然后发送
最后发真实内容

接收时:
先手报头长度,用struct取出来
根据取出的长度收取报头内容,然后解码,反序列化
从反序列化的结果中取出待取数据的详细信息,然后去取真实的数据内容

3、基于UDP协议通信的套接字
UDP是基于数据报的,一发对应一收
特点:无连接
优点:发送效率高,但有效传输的数据量最多为512bytes
缺点:不可靠(发送数据无须对方确认,容易丢包)

猜你喜欢

转载自www.cnblogs.com/Python1/p/8981914.html