file transfer
Basic file transfer (small file)
#The server is responsible for receiving
import socket
import json
sk = socket.socket()
sk.bind(('127.0.0.1', 5002))
sk.listen()
conn, addr = sk.accept()
msg_ f = conn.recv (1024). Decode ('utf-8 '), which receives the file information from the client
dic_ f = json.loads (msg_ f)# json.loads () is used to convert data in string form into a dictionary
with open(dic_f['filename'], mode='wb') as f:
file = conn.recv (dic_ F ['File size ']) ා receives the file with the size of the file sent
f.write(file)
conn.close()
sk.close()
##############################################
#The client is responsible for sending
import socket
import os
import json
sk = socket.socket()
sk.connect(('127.0.0.1', 5002))
abs_path = r'D:.jpg'
filename = os.path.basename(abs_path)
filesize = os.path.getsize(abs_path)
dic = {'filename': filename, 'filesize': filesize}
str_ dic = json.dumps (dic)# json.dumps () is used to convert dictionary data into strings
sk.send (str_ dic.encode ('utf-8 ')) ා transfer the file information to the server
with open(abs_path, mode='rb') as f:
file = f.read()
sk.send(file)
sk.close()
- The above server side is responsible for receiving, and the client side is responsible for sending. After running, 1.jpg file appears in the current directory.
- The above code can only transfer small files, and there are many hidden dangers, such as STR in the process of transmission_ When DIC is greater than 1024 bytes, the file information received by the server will be wrong, and there will be more problems when transferring large files.
Large file transfer
#Responsible for receiving
import socket
import json
import struct
sk = socket.socket()
sk.bind(('127.0.0.1', 5002))
sk.listen()
conn, addr = sk.accept()
lens = conn.recv(4)
lens = struct.unpack('i', lens)[0]
msg_ f = conn.recv (lens). Decode ('utf-8 '), which receives the file information from the client
dic_ f = json.loads (msg_ f)# json.loads () is used to convert data in string form into a dictionary
with open(dic_f['filename'], mode='wb') as f:
while dic_f['filesize'] > 0:
file = conn.recv(1024)
dic_f['filesize'] -= len(file)
f.write(file)
conn.close()
sk.close()
############################################################
#Responsible for sending
import socket
import os
import json
import struct
sk = socket.socket()
sk.connect(('127.0.0.1', 5002))
abs_path = r'C:\Users\LENOVO\Pictures\Camera Roll\WIN_20200301_14_36_34_Pro.mp4'
filename = os.path.basename(abs_path)
filesize = os.path.getsize(abs_path)
dic = {'filename': filename, 'filesize': filesize}
str_ dic = json.dumps (dic)# json.dumps () is used to convert dictionary data into strings
#In order to avoid sticking
b_dic = str_dic.encode('UTF-8')
lens = struct.pack ('i', len(b_ DIC)) ා convert the length of the file information to be transferred into 4 bytes
sk.send(lens)
sk.send (b_ DIC) ා transfer the file information to the server
with open(abs_path, mode='rb') as f:
#Transfer large files with circular reading
while filesize > 0:
File = f.read (1024) ා 1024 bytes read each time
filesize -= 1024
sk.send(file)
sk.close()
- After running, the corresponding MP4 file appears in the current directory, and it is a 144m large file.
- In order to avoid the phenomenon that the length of the received file will be 1024 bytes less than the length of the received file, the length of the received file will be 1024 bytes less than the length of the received file.
- In order to avoid this phenomenon, we need to send the length of the file information to the server in the form of 4 bytes, and then receive the file with the corresponding length.
Client legitimacy
- If the client wants to connect with the server, the server must pass the legal authentication, and verify the validity of the client through the agreed key.
- The server randomly sends information to the client requesting connection. The client gets a result by hashing the received information plus the agreed key, and sends the result to the server.
- At the same time, the server will send the random information and key through the hash algorithm to get a result. This result is compared with the result received from the client. If the result is consistent, it will pass the legal verification.
- Note: the key cannot be sent directly through the network, which may be blocked.
Hash algorithm: through a function, any length of data into a fixed length of data string (usually expressed in hexadecimal string). In other words, the summary function f () is used to calculate the fixed length digest of any length of data in order to find out whether the original data has been tampered with.
#Server
import socket
import os
import hashlib
import hmac
key = b'password'
msg_ rand = os.urandom (16) Generate random information of 16 bit type bytes
sk = socket.socket()
sk.bind(('127.0.0.1', 5002))
sk.listen()
conn, addr = sk.accept()
conn.send (msg_ Send 16 bit random information
#According to the random information and the key to abstract
'''
#MD5 in hashlib module can be used, or SHA1 can be used
md5 = hashlib.md5(key)
md5.update(msg_rand)
Res = MD5. Hexdigest(). Encode ('utf-8 ') # the summary result is STR type
'''
#Using HMAC module
hm = hmac.new(key, msg_rand)
res = hm.digest () ා at this time, the summary result is of type bytes
msg_res = conn.recv(32)
if res == msg_res:
Print ('legal client ')
conn.send(b'hello')
else:
conn.close()
sk.close()
########################################################
#Client side
import socket
import hashlib
import hmac
key = b'password'
sk = socket.socket()
sk.connect(('127.0.0.1', 5002))
msg_ rand = sk.recv (16) Receiving random information
'''
md5 = hashlib.md5(key)
md5.update(msg_rand)
res = md5.hexdigest().encode('UTF-8')
'''
hm = hmac.new(key, msg_rand)
res = hm.digest()
sk.send(res)
msg = sk.recv(1024)
print(msg)
sk.close()
Sockesever module
-
The socket sever module is based on the socket module.
-
Sever, which is commonly used in TCP protocol, processes concurrent client requests.
-
At this time, multiple clients can communicate with sever.
#Sever end import time import socketserver class Mysever(socketserver.BaseRequestHandler): def handle(self): conn = self.request while True: #Small messages can be sent repeatedly try: msg_r = conn.recv(1024).decode('UTF-8') conn.send(msg_r.upper().encode('UTF-8')) time.sleep(0.5) except ConnectionResetError: break sever = socketserver.ThreadingTCPServer(('127.0.0.1',5002), Mysever) sever.serve_forever()#Sever end不主动退出 ###################################################################### #Client-n terminal import time import socket sk = socket.socket() sk.connect(('127.0.0.1', 5002)) while True: sk.send(b'hello') msg = sk.recv(1024).decode('UTF-8') print(msg)