文章目录
- 传输模型
- TCP协议
- 建立套接字
- 传输数据
- 总结
一.传输模型
一.1.1层次模型
会层说民 | OSI七层模型 | TCP/IP四层网络模型 | 对应协议 |
---|---|---|---|
供操作系统或应用网络通信的标准 接口 | 应用层 | 应用层 | Telnet FTP SMTP DNS HTT P |
将不同的编码方式转换成网络通信 中采用的标准表示形式(如:UTF-8) | 表示层 | ||
不同PC不同进程间建立或解除链接, 插入同步点 | 会话层` | ||
两个主机间端对端的数据连接与传 输 | 传输层 | 传输层 | TCP UDP |
选择路由并正确的在找着目标主机 | 网络层 | 网络层 | IP ARP RARP ICMP |
两个相邻节点间准确的数据传输 | 数据链路层 | 数据链路层 | 网络通信硬件及接口 |
原始比特数据在物理介质上的传输 | 物理层 |
一.1.2应用层
- http : 超文本传输协议,使用浏览器查询web服务器之间的传输的协议
- ftp : 文件传输协议,实现网上与主机之间文件交换的协议
- smtp : 简单邮件传输协议,定义了邮件如何在邮件服务器之间传输的协议
- pop : 邮件协议,定义了将用户从邮件服务器下载到本地服务器的协议
- Telent :远程登录协议,远程使用网上其他计算机使用的协议,以获取其他计算机上运行 或存储信息
- DNS :域名系统,实现域名到IP地址之间的转换
一.1.3传输层
定义 :网络协议是通信双方就通信如何进行所必须共同遵守的约定和通信规则集合。 在网络上通信的双方只有遵守相同的协议,才能正确地交流信息
TCP | UDP |
1.通过三次握手协议建立稳定连接 | 1.一次性发送所有数据,无需建立连接 |
2.应用数据分割成最合适的数据块发送 | 2.服务器可以同时发送多个客户机 |
3.连接可靠,不易出现程序、丢失等现象 | 3.没有检验,容易出现信息丢失 |
4.连接和检验都需要花不少时间,效率因此会降低 | 4.消耗资源小,处理速度快 |
一1.4网络层
- IP : 因特网上的每台计算机和其它设备都规定了一个地址,叫做IP地址
- ARP : 地址转协议,完成IP地址到物理地址的转化
- RARP : 反向地址转换协议,完成物理地址到IP地址的转换
- ICMP : 控制报文协议,发送消息,并且报告数据包的传送错误
一1.5 IPV4和IPV6
ipv4是第一个被广泛应用的ip,IP是TCP/IP协 议族中网络层的协议,是TCP/IP协议的核心 协议 ipv4的地址长度规定为32位,分为四段, 每段8位且以点隔开,并以十进制形式表示, 故 每 段 的 数 值 范 围 为 0~255, 即最小的为 0.0.0.0,最大为255.255.255.255. 由于ipv4位数使用地址资源已被分配完, 故产生了ipv6。 ipv6的 长度是ipv4的四倍,以十六进制形 式表示,其被分为8段,每段以冒号隔开。 其中地址块127.0.0.1被保留作环回通信用, 0.0.0.0为任意使用。
一.1.6 端口
提示 : 此处详细见网址: 端口_百度百科
特别记忆 :
端口不能小于1024 1024以下都是被系统占用了
3306是MySQL数据库的端口号
A电脑 <------双方电脑上同时运行很多程序,如何保证是对应程序接受到呢------> B电脑
当同时多个程序使用网络时,为了保证信息发送到正确的地方,增加了端口,不同的软件使用不同的端口,虽然使用同一个网络,但是因为端口不一样,也能保证信息发给正确的人.
端口号正确的范围从 0 到 65535(2~16-1),例 : 用于浏览器网页服务的80端口,用于FTP服务的21端口等等.
IP 地址用于区分不同的主机,而端口号用于区分一个主机下的不同网络服务
二 TCP协议
二.1.1建立连接
三次握手:
第一步:客户端发送SYN报文给服务端, 进入SYN_SEND状态
第二步:服务器端收到SYN报文,进入 SYN_RECV状态。
第三步:客户端收到服务器端的SYN报文, 回应一个ACK报文,进入Establishd状态 三次握手完成,TCP客户端和服服务器端 成功地建立连接,可以开始传输数据了
解 :
第一步,你给你女朋友打电话,
第二步,你女朋友收到电话提示
第三步,你女朋友收到电话提示并且给予你回复
第四步,开始正常闲聊 (握手成功)
二.1.2断开连接
四次挥手:
第一步:先由客户端向服务器端发送一个 FIN,请求关闭数据传输
第二步:当服务器接收到客户端的FIN时, 向客户端发送一个ACK,其中ack的值等于 FIN+SEQ 第三步:然后服务器向客户端发发送一个 FIN,告诉客户端应用程序关闭
第四步:当客户端收到服务器的FIN时,回 复一个ACK给服务器。其中ack的值等于 FIN+SEQ
解:
第一步,你给你女朋友发一个信息,问是否可以打电话
第二步,女朋友回复可以,然后开启打电话
第三步,收到电话提示
第四步,接听后开始电话闲聊
二.1.3长连接与短连接
- 短连接:
建立连接——数据传输——关闭连接…建议连接——数据传输——关闭连接
解:
跟女朋友信息闲聊
- 长连接:
建立连接——数据传输…(保持连接)…数据传输——关闭连接
解:
跟女朋友打电话八卦唠嗑
三建立套接字
三.1.1服务端
#1.导包
import socket
#2.创建服务/创建对象
server = socket.socket()
#3.绑定IP和port
server.bind(('127.0.0.1', 8989)) #端口号必须大于1024 1024属于系统在用端口号
#print(server)
#4.监听
server.listen(10) #防止撑爆
#5.创建套接字
result = server.accept()
#print(result)
conn, add = result #元组拆包
#print(conn)
#print(addr)
conn.send('星月加油'.encode('utf-8'))
#6.接收消息
data = conn.recv(1024).decode('utf-8')#1024表示字节 : 数据大小
print(data)
三.1.2客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8989)) #连接服务端
#client.send(b'hello') #发送数据(需要二进制数据(字节数据))
client.send('星月继续加油'.encode('utf-8'))
#接受数据
data = client.recv(1024).decode('utf-8')
print(data)
三.1.3对等连接套接字
#套接字
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #socket.AF_INE : ipv4 socket.SOCK_STREAM : TCP
#绑定IP 和 端口
server.bind(('127.0.0.1',10086))
#监听
server.listen(9)
#接受客户连接
conn, add = server.accept()
print(add,'您有新的信息')
对等连接套接字 要想发送数据,还需要对等连接套接字
四.传输数据
1.
#服务端
conn.send('星月加油'.encode('utf-8'))
#6.接收消息
data = conn.recv(1024).decode('utf-8')#1024表示字节 : 数据大小
print(data)
#客户端
#client.send(b'hello') #发送数据(需要二进制数据(字节数据))
client.send('星月继续加油'.encode('utf-8'))
#接受数据
data = client.recv(1024).decode('utf-8')
print(data)
4.1.2关闭
#服务端
conn.close()
server.close()
#客户端
client.close()
4.1.3阻塞
当客户端没有连接,或者发送数据的时候,服务端执行 accept和recv都会产生阻塞
- 单工:广播,只收对方的信息,只发不收
- 半双工:同一时刻只能有一个人讲
- 全双工:可以同时讲和收
解:
单工:只收到女朋友信息,不回
半双工:电话是只有女朋友在讲
全双工:跟女朋友说说笑笑
总结
完整代码
#服务端
import socket
print('星月测试')
#套接字
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #socket.AF_INE : ipv4 socket.SOCK_STREAM : TCP
#绑定IP 和 端口
server.bind(('127.0.0.1',10086))
#监听
server.listen(9)
#接受客户连接
conn, add = server.accept()
print(add,'您有新的信息')
#回复信息
data = conn.recv(1024).decode('utf-8')
print(data)
conn.send(input('>>>>').encode('utf-8'))
conn.close()
server.close()
#客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',10086))
client.send(input('>>>>').encode('utf-8'))
data = client.recv(1024).decode('utf-8')
print(data)
client.close()