Python学习笔记Day08 - 网络协议、socket
目录
https://www.cnblogs.com/alex3714/articles/5227251.html
1.网络协议:http,smtp,dns,ftp,ssh, snmp, icmp, dhcp
本质上只做send,receive两件事
2.socket:将send,receive封装,协议直接调用即可
3.ip与port
4.粘包:连续send两次,缓冲区会导致两次数据粘在一起发送(可以插入一次recv)
5.socket模拟
socket服务端
import socket
import os
server = socket.socket() # 1创建服务器socket
server.bind(('0.0.0.0', 9999)) # 2绑定端口
server.listen() # 3监听
print('开始等电话')
conn, addr = server.accept() # 4收到请求,创建新连接实例
print(conn, addr)
print('收到电话')
while True:
data = conn.recv(1024) # 5接收数据,大小1024bites
if not data:
print('客户端已断开')
break
conn.send(data.upper())
print('返回其大写')
server.close()
socket客户端
import socket
client = socket.socket() #1声明socket类型,同时生成socket连接对象
client.connect(('localhost',9999)) #2连接端口
while True:
msg = input('>>:').strip()
if len(msg) == 0:continue
client.send(msg.encode()) #3发送信息
serverResponse = client.recv(1024) #4接收信息
print('server response:',serverResponse.decode())
6.ftp模拟
ftp服务端
import socket
import hashlib
import os
server = socket.socket() # 创建服务器
server.bind(('0.0.0.0', 9999)) # 绑定端口
server.listen() # 监听
while True: # 多用户
conn, addr = server.accept() # 收到请求,创建新连接
print('new coon:', addr)
while True: # 循环接收指令
print('等待新指令')
data = conn.recv(1024) # 接收数据,大小1024bites
if not data:
print('客户端已断开')
break
cmd, filename = data.decode().split()
print(filename)
if os.path.isfile(filename): # 确认文件存在
with open(filename, 'rb') as f:
# m = hashlib.md5()
m = hashlib.md5(f.read())
f.seek(0)
fileSize = os.stat(filename).st_size
conn.send(str(fileSize).encode()) # 返回文件总大小
conn.recv(1024) # 等待确认
print('正在发送文件')
sentSize = 0
for line in f:
# m.update(line)
conn.send(line)
sentSize += len(line)
print('已发送', sentSize)
conn.send(m.hexdigest().encode())
print('文件发送完毕')
ftp客户端
import socket
import hashlib
client = socket.socket()
client.connect(('localhost', 9999))
while True:
cmd = input('>>:').strip()
if len(cmd) == 0: continue
if cmd.startswith('get'):
client.send(cmd.encode())
serverResponse = client.recv(1024)
print('fileSize:', serverResponse)
client.send(b'ready to recv file')
fileSize = int(serverResponse.decode())
filename = cmd.split()[1]
suffix = filename.rsplit('.', 1)[1]
newFilename = '%s_new.%s' % (filename.rstrip('.%s' % suffix), suffix)
with open(newFilename, 'wb') as f:
recvSize = 0
m = hashlib.md5()
while recvSize < fileSize:
if fileSize - recvSize > 1024: # 不止一次
size = 1024
else:
size = fileSize - recvSize
data = client.recv(size)
recvSize += len(data)
m.update(data)
f.write(data)
else:
newMd5 = m.hexdigest()
print('文件接收完毕:', recvSize)
print('new md5:',newMd5)
originMd5 = client.recv(1024).decode()
print('origin md5:',originMd5)
if newMd5 == originMd5:
print('文件成功接收')
else:
print('文件传输错误')
client.close()
7.socketserver:对socket的封装,简化
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
while True:
try:
self.data = self.request.recv(1024).strip()
print(self.data)
except ConnectionResetError as e:
print('error:', e)
break
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
# Create the server, binding to localhost on port 9999
server = socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler)
server.serve_forever()