先发送一下数据有多大,再按照数据长度接收数据

  要在文件中配置一个配置项:每次recv的大小,默认缓冲区buffer = 4096

  要发送大数据的时候,要明确告诉接收方要发送多大的数据,以便接收方准确接收到所有数据

  多用在文件传输过程中

  大文件的传输一定是按照字节读,每次读固定的字节

  传输的过程中一边读一边传,接收端一边收一边写

SEVER:

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()

conn, addr = sk.accept()
while True:
cmd = input('>>>')
if cmd == 'q':
conn.send(b'q')
break
conn.send(cmd.encode('gbk'))
num = conn.recv(1024).decode('utf-8')
print(num)
conn.send(b'ok')
ret = conn.recv(int(num)).decode('gbk') #好处:确定了到底要接受多大数据,缺点:多一次交互
print(ret)

conn.close()
sk.close()

CLIENT:

import socket
import subprocess
sk = socket.socket()
sk.connect(('127.0.0.1',8090))
while 1:
cmd = sk.recv(1024).decode('gbk')
if cmd == 'q':
break
ret = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
std_out = ret.stdout.read() #管道中的数据只能取一次
std_err = ret.stderr.read()
sk.send(str(len(std_out)+len(std_err)).encode('utf-8'))
sk.recv(1024)
sk.send(std_out)
sk.send(std_err)
sk.close()

###########################################

struct模块:

借助struct模块吧长度数字转换成一个标准大小的4字节数字

SEVER:

import socket
import struct
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()

conn, addr = sk.accept()
while True:
cmd = input('>>>')
if cmd == 'q':
conn.send(b'q')
break
conn.send(cmd.encode('gbk'))
num = conn.recv(4)
num = struct.unpack('i',num)[0]
ret = conn.recv(int(num)).decode('gbk')
print(ret)

conn.close()
sk.close()

CLIENT:

import socket
import subprocess
import struct
sk = socket.socket()
sk.connect(('127.0.0.1',8090))
while 1:
cmd = sk.recv(1024).decode('gbk')
if cmd == 'q':
break
ret = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
std_out = ret.stdout.read() #管道中的数据只能取一次
std_err = ret.stderr.read()
len_num = len(std_out)+len(std_err)
num = struct.pack('i',len_num)
sk.send(num)
sk.send(std_out)
sk.send(std_err)
sk.close()