一、什么是socket:
套接字socket: 在python中就是一个模块, socket是在应用层与传输层中间的抽象层.
socket就像是一个接口,通过这个接口可以实现网络通信.
它把复杂的TCP/IP协议族隐藏在Socket接口后面,socket屏蔽了各个协议的通信细节,使得程序员无需关注协议本身,直接使用socket提供的接口来进行互联的不同主机间的进程的通信。
socket根据用途,有两种分类:
1)基于文件类型的套接字家族:AF_UNIX, 基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,可以通过访问同一个文件系统间接完成通信
2)基于网络类型的套接字家族(AF_INET):网络编程就是用的 AF_INET
osi七层模型: 互联网的核心就是由一堆协议组成,协议就是标准,标准就是大家都认可的,下面的图是数据通过网络沟通经过的底层细节.主要记住五层就够了
socket 在网络流程中的位置:应用层与传输层之间
简述访问Jd网站流程
二、基于TCP和UDP两个协议下的socket的通讯流程
什么是TCP: 可靠的、面向连接的协议,传输效率低全双工通信(发送缓存&接收缓存)、面向字节流. 比如:Web浏览器,文件传输程序。
什么是UDP:不可靠的、面向无连接的服务,传输效率高(发送前时延小),既可多对多,也可一对多,无拥塞控制,面向报文(以包的形式发送). 比如:域名系统 (DNS),视频流,IP语音(VoIP)。
tcp的连接需要经过三次握手,断开需要经过四次挥手:
UDp的连接和断开不需要三握和四挥.
网络传输ios五层流程图:
pycharm里面默认用的是网络家族的TCP(字节流数字流)协议
三、基于UDP协议下的socket网络通话.(type=cocket.SOCK_DGRAM)可以多人连接通话 datagram(数据包)
UDP协议下不会产生粘包现象,因为有消息边界,每次发送,都是以包的形式发送(有包头和消息组成),对方取值是,如果取值的"勺子"(recvfrom(n)的参数)设置的太小,就会出异常; 当太大时,一次只会取一个包.所以不会出现粘包现象.
UDP服务端:这里的recvfrom(1024)是UDP特有;TCP是recv(1024)设置从缓存取每次取值的大小,单位为字节)
UDP客户端:
四、TCP通话(允许多人通话,但需要排队,跟一个客户端了之后才能跟下一个客户连接.),服务端:(addr是地址的缩写)
import socket #建立网络通信的模块 xiaoli = socket.socket() xiaoli.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) ip_xiaoli = ("127.0.0.1",8001) xiaoli.bind(ip_xiaoli) #侦听ip地址和端口,简称开机 xiaoli.listen(3) #默认为1,连接一个通道,可以配置,表示连接一个通道后,允许其他对象重用我的IP地址进行通话,但需排队等待 while 1: # 等待建立连接, conn是连接通道,addr是客户端的地址 conn,addr=xiaoli.accept() print(addr) #查看客户端地址 while 1: # 服务端通过conn连接通道来收发消息,通过recv方法,recv里面的参数是字节(B),1024的意思1024B=1KB kehu_xiaoxi = conn.recv(1024).decode("utf-8") print("客户端告诉你>>>",kehu_xiaoxi) if kehu_xiaoxi=="byebye": break # 回复消息:通过send方法,参数必须是字节类型的, tiwen = input("请输入内容:").encode("utf-8") conn.send(tiwen) conn.close()
TCP多人通话,客户端:(#客户端的设置比服务端简单,省去了:侦听IP地址和设置消息通道,发送消息直接用实例对象.recv就行)
import socket xiaohei = socket.socket() #连接服务端的应用程序,通过connect方法,参数是服务端的ip地址和端口,打电话 xiaohei.connect(("127.0.0.1",8001)) while 1: tiwen1 = input("输入你想说的话:") xiaohei.send(tiwen1.encode("utf-8")) if tiwen1=="byebye": break duixiang = xiaohei.recv(1024).decode("utf-8") print("服务端说>>>",duixiang) xiaohei.close()
五、小练习:TCP客户端每个2秒发送一条时间戳给TCP服务端,TCP服务端吧它转换成格式化时间.
TCP服务端:
TCP客户端(time sleep(t) 函数推迟调用线程的运行,可通过参数secs指秒数,表示进程挂起的时间,t -- 推迟执行的秒数)