复习
上节课复习: 1、C/S B/S client----- server browser-----server 其中服务端必须具备: 1、稳定运行,对外一直提供服务 2、绑定一个固定的ip+port 2、互联网: 2.1 物理连接介质 2.2 互联网协议(互联网协议即计算机界的英语) 3、tcp 三次握手 半连接池backlog=5 限制的同一时刻的请求数而非连接数 四次挥手断开连接 今日内容: 1、基于socket编写C/S架构的软件 基于tcp协议 2、tcp协议的粘包问题
基于tcp协议的套接字通信
import socket #1、买手机 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #tcp称为流式协议,udp称为数据报协议SOCK_DGRAM # print(phone) #2、插入/绑定手机卡 # phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) phone.bind(('127.0.0.1',8080)) #3、开机 phone.listen(5) # 半连接池,限制的是请求数 #4、等待电话连接 print('start....') while True: # 连接循环 conn,client_addr=phone.accept() #(三次握手建立的双向连接,(客户端的ip,端口)) # print(conn) print('已经有一个连接建立成功',client_addr) #5、通信:收发消息 while True: # 通信循环 try: print('服务端正在收数据...') data=conn.recv(1024) #最大接收的字节数,没有数据会在原地一直等待收,即发送者发送的数据量必须>0bytes # print('===>') if len(data) == 0:break #在客户端单方面断开连接,服务端才会出现收空数据的情况 print('来自客户端的数据',data) conn.send(data.upper()) except ConnectionResetError: break #6、挂掉电话连接 conn.close() #7、关机 phone.close()
import socket #1、买手机 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # print(phone) #2、拨电话 phone.connect(('127.0.0.1',8080)) # 指定服务端ip和端口 #3、通信:发收消息 while True: # 通信循环 msg=input('>>: ').strip() #msg='' if len(msg) == 0:continue phone.send(msg.encode('utf-8')) # print('has send----->') data=phone.recv(1024) # print('has recv----->') print(data) #4、关闭 phone.close()
访问过程 应用层数据--os(协议层:端口,加tcp头,加ip头,找网关mac,二进制数----网络传输----物理层,数据层,网络层,传输层,应用层)
dns:横向递归查询 纵向迭代查询
##1 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。 ##2 一开始,套接字被设计用在同 一台主机上多个应用程序之间的通讯。这也被称进程间通讯,或 IPC。套接字有两种(或者称为有两个种族),分别是基于文件型的和基于网络型的。 基于文件类型的套接字家族 套接字家族的名字:AF_UNIX 基于网络类型的套接字家族 套接字家族的名字:AF_INET ##3 先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束 ##4 服务端套接字函数 s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连接,(阻塞式)等待连接的到来 客户端套接字函数 s.connect() 主动初始化TCP服务器连接 公共用途的套接字函数 s.recv() 接收TCP数据 s.send() 发送TCP数据(send在待发送数据量大于己端缓存区剩余空间时,数据丢失,不会发完) s.close() 关闭套接字 ##5 tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端