传输模型:1、传输模型基本模型: 2、TCP协议OSI七层模型
TCP/IP四层模型:先有协议和应用,再有模型 TCP建立连接:三次握手
数据传输 断开连接:四次挥手 客户端:我要关闭连接了 为什么多了一次: 到底是一次连接传一次数据 3、IP地址和端口不同主机之间通信,先用ip确定某个主机,再用端口确定某一个应用程序。 除了一些服务占用的端口外,其他端口由操作系统分配,总共65535端口 套接字:1.创建套接字实例import socket sock = socket.socket() print(sock) <socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
domain:(域) AF_INET6 ipv6 type:(套接字类型): SOCK_STREAM 字节流套接字 ——>提供顺序,可靠,双向,基于连接的字节流。 可以支持带外数据传输机制。例如:TCP协议、FTP协议 SOCK_DGRAM 数据报套接字 ——>支持数据报(无连接,不可靠的固定最大长度的消息)例如:UDP协议 SOCK_SEQPACKET 有序分组套接字 ——>为固定最大长度的数据报提供有序,可靠,双向连接的数据传输路径; 消费者需要利用每个输入系统调用读取整个分组 protocol(协议): IPPROTO_IP IP传输协议 IPPROTO_TCP TCP传输协议 IPPROTO_UDP UDP协议 IPPROTO_SCTP SCTP传输协议 IPPROTO_ICMP ICMP协议 IPPROTO_IGMP IGMP协议 一般情况下IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP协议用的最多,UDP协议protocol就取IPPROTO_UDP,TCP协议protocol就取IPPROTO_TCP;一般情况下,我们让protocol等于0就可以,系统会给它默认的协议。但是要是使用raw socket协议,protocol就不能简单设为0,要与type参数匹配. 三种套接字 2.建立连接服务端的端口不能由操作系统分配(一般是固定的,让客户端知道要请求哪个端口) sock.bind(('',8888)) #服务端套接字绑定自己的IP地址与端口号,客户端那边可以不写,内核会给它分配一个临时的端口.不写就是绑定到本地,后面8888是端口 sock <socket.socket fd=724, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 9999)> sock.listen(5) #开始监听,5表示最大挂起数 客户端套接字 client = socket.socket() client.connect(('127.0.0.1',9999)) client <socket.socket fd=872, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 58311), raddr=('127.0.0.1', 9999)> laddr表示本地地址,raddr表示远程连接的地址 t = sock.accept() # 实例一个对等连接套接字,用来和客户端通信。如果没有客户端连接,会处于阻塞状态 t (<socket.socket fd=676, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 58311)>, ('127.0.0.1', 58311)) conn, addr = t # conn现在是连接套接字,addr是客户端地址和端口 3.发送接受消息client.send(b'hello') # 客户端发送消息(字节类型,如果是字符串记得要encode),返回数据长度.客户端断开连接之后,会发送一个b''空字节 conn.recv(1024) # 连接套接字接收消息,1024表示每次最大接收数据大小,可以通过循环把所有数据接受完,接收的消息是字节类型,记得decode。如果没有数据发过来,会处于阻塞状态 4.断开连接client.close() #客户端程序运行完会自己断开 conn.close() #服务端可以根据是否接到空,判断是否需要断开 |
|