TCP协议
在连接内多和客户端说几句
#server端
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
while True
conn,addr = sk.accept()
while True
bad = input('>>>')
conn.send(bad.encode('utf-8'))
if bad.upper() == 'Q':
break
msg = conn.recv(1024).decode('utf-8')
if msg.upper == 'Q':break
print(msg)
conn.close() #挥手 断开连接
sk.close() #归还申请的操作系统资源
#client
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
while True:
msg = sk.recv(1024)
msg2 = msg.decode('utf-8')
if msg2.upper == 'Q':break
print(msg2)
send_msg = input('>>>')
sk.send(send_msg.encode('uft-8'))
if send_msg.upper == 'Q':break
sk.close()
为什么要加while True
- 因为要进行多次通信
sk代表什么?
- sk代表启用的通信服务
conn代表什么?
- conn代表自己的IP地址,和对方的地址和端口
能够接受多个客户端的请求
- 为什么加while True
- 因为在一个客户端断开连接之后不能管不服务,要等待另一个客户端连接
- 怎么退出
- 在接收或者传输的时候先检查是不是要退出,要是退出的话就break
UDP协议
语法:
#server
import socket
sk = socket.socket(tyep = socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',9000))
msg,addr = sk.recvfrom(1024)
print(msg.decode('utf-8'))
msg = input('>>>')
sk.sendto(msg.encode('utf-8'),addr)
#client
import socket
sk = socket.socket(type = socket.SOCK_DGRAM)
server = ('127.0.0.1',9000)
while True:
msg = input('>>>')
if msg.upper == 'Q':break
sk.sendto(msg.encode('utf-8'),server)
msg = sk.recv(1024).decode('utf-8')
if msg.upper() == 'Q':break
print(msg)
涉及到的新方法
- type = socket.SOCK_DGRAM 在开启socket方法的时候加上这段代码,表示就是用UDP协议
- recvfrom:在server端接收信息的时候用recvfrom就可以把客户机的IP地址获取到
和TCP协议的区别
- 它可以同时建立多个连接,当一个连接断开后不会影响其他连接
粘包现象
- TCP协议的特点
- 多条消息之间没有边界,并且还有一大堆优化算法
- 什么叫做粘包
- 多条数据粘在一起
- 为什么会出现粘包
- 发送端:两条消息都很短,发送的间隔时间也非常短
- 接收端:多条消息由于没有及时接收,而在接收方的缓存短堆在一起导致粘包
- 怎么处理
#server
import struct
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9001))
sk.listen()
conn,addr = sk.accept()
msg1 = input('>>>').encode()
msg2 = input('>>>').encode()
blen = struct.pack('i',len(msg1))
conn.send(blen)
conn.send(msg1)
conn.send(msg2)
sk.close()
#cilent
import struct
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',9001))
length = sk.recv(4)
length = struct.unpack('i',length)[0]
msg1 = sk.recv(length)
msg2 = sk.recv(1024)
print(msg1.decode('utf-8'))
print(msg2.decode('utf-8'))
sk.close()
什么叫自定义协议
- 在网络传输的时候,人为的为它定制一个协议,让它遵守此项协议
struct模块怎么用
- struct.pack()#将一个数字转换为4个字节的数
- struct.unpack()#将一个4个字节的数,转化回原来的数
osi五层协议
- 应用层
- 传输层
- tcp协议:效率低 面向连接、可靠、全双工的通信
- 三次握手
- 客户端向服务器端发送syn请求
- 服务器端向客户端回复ack并发送syn请求
- 客户端接收到的请求之后再回复ack表示建立连接
- 由客户端的connect + 服务端的 close
- 四次挥手
- 客户端向服务端发送fin请求
- 服务端回复ack确认
- 服务端向客户端发送fin请求
- 客户端回复ack
- 由客户端的close和服务端的close
- 三次握手
- udp协议:效率高 无连接的、不可靠
- 四层交换机,四层路由器
- tcp协议:效率低 面向连接、可靠、全双工的通信
- 网络层
- IP协议(ipv4,ipv6)
- 路由器、三层交换
- 数据链路层
- arp协议,地址解析协议 通过IP找到mac地址
- 物理层