TCP to transfer files to solve the stick package +

# Solve the stick package
** Only TCP packet has a sticky phenomenon, UDP never stick package **

** ** stick package is essentially the reason I do not know how much to charge
1.tcp once received too much, next time it needs the receiving end, resulting in sticky package
2.tcp sent to the kernel mode memory content of the message is less of a few, there Nigon TCP algorithm, the less a synthesis of multiple content packages, operating system, and then sent out, so the client only received once, on the whole received

TCP: A end and B-end communication connection, A Send side, B side can receive
UDP: A first end of the sendto, B must have a recvfrom end corresponding, B can end actually received
UDP if a hair> once received, not received all lost part

** ** Solutions
1. First hair volume data, the second retransmission data
2. Before the selected n bytes, containing the length of the rest of the data

** ** jason solution header to dict, access to additional information file, to facilitate subsequent processing
server
`` `Python
Import socket
Import subprocess
Import struct
Import json

server = socket.socket()
server.bind(('127.0.0.1',8081))
server.listen(5)

True the while:
Conn, addr = server.accept ()
Print ( 'successful connection')
the while True:
the try:
cmd = conn.recv (1024)
Print ( 'successful reception')
# TCP clients send null, will lead to the server ram live (udp do not have this problem, because that comes with the header, address and port information)
IF len (cmd) == 0: BREAK
cmd = cmd.decode ( 'UTF-8')
# use subprocess to open a new process, may receive commands and calls the shell to execute this string
obj = subprocess.Popen (cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
#res receiving subprocess output of shell standardization and standardized report false information
res = obj.stdout.read () + obj.stderr.read ()
# length, and other information required to provide the information returned by the module, make the dictionary
d = { 'file_size': len (res), 'info': 'XXXXXXX'}
# Dictionary serialization
json_d = json.dumps (D)
# 1. first make a prompt client, the length of the dictionary to be transmitted header
# (struct module, the type int length, converted into a binary string, only 4 bytes)
= struct.pack header ( 'I', len (json_d))
# Header2 struct.pack = ( 'I', len (json_d.encode ( 'UTF8'))) with the same effect on the sentence, the length of bytes is counted

# 2 send dictionary header
conn.send (header)
# 3. send dictionary
conn.send (json_d.encode ( 'UTF-. 8'))
# 4. recurrent real data
conn.send (RES)
# conn.send ( obj.stdout.read ())
# conn.send (obj.stderr.read ())
the except ConnectionResetError:
BREAK
conn.Close ()
`` `

The client
`` `Python
Import socket
Import struct
Import json

= socket.socket Client ()
the client.connect (( '127.0.0.1', 8081))
Print ( 'successful connection')
the while True:
MSG = INPUT ( '>>>:'). encode ( 'UTF-. 8' )
# tcp client made empty, the server can cause this problem rammed live (udp does not exist, because that comes with the header, address, and port)
IF len (msg) == 0: the Continue
client.send (msg)
# 1. dictionary received first header
header_dict client.recv = (. 4)
# 2. acquired dictionary parses header length
dict_size = struct.unpack ( 'i', header_dict) [0] # unpacking time must be indexed and 0
# 3. Receive data dictionary
dict_bytes = client.recv (dict_size)
dict_json = json.loads (dict_bytes.decode ( 'UTF-. 8'))
# 4. to obtain information from the dictionary
recv_size = 0
real_data = B ''
# must be < , if the last time that could have been just finished i.e. recv_size = dict_json, big deal once again receives
# = if changed, would have the last harvested, still satisfy determination conditions,Received is empty, the ram will live
while recv_size < dict_json.get('file_size'):
data = client.recv(1024)
real_data += data
recv_size += len(data)
print(real_data.decode('gbk'))
```

** ** Egon解决办法
https://www.cnblogs.com/coser/archive/2011/12/17/2291160.html
https://www.cnblogs.com/gala/archive/2011/09/22/ 2184801.html
服务端
`` python
from socket import *
import subprocess
import struct
ip_port = ( '127.0.0.1', 8080)
back_log = 5
buffer_size = 1024

tcp_server=socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)

True the while:
conn, addr = tcp_server.accept ()
Print ( 'new client links', addr)
the while True:
# close
the try:
cmd = conn.recv (buffer_size)
IF not cmd: BREAK
Print (' receipt of customer end of command ', cmd)

Run #, command operation results obtained cmd_res
RES = subprocess.Popen (cmd.decode ( 'UTF-. 8'), the shell = True,
stderr = subprocess.PIPE,
stdout = subprocess.PIPE,
stdin = subprocess.PIPE)
ERR res.stderr.read = ()
IF ERR:
cmd_res ERR =
the else:
cmd_res = res.stdout.read ()

# Hair
IF not cmd_res:
cmd_res = 'successfully executed' .encode ( 'gbk')

len = length (cmd_res)
# according to the given format (FMT), the data is encapsulated into a string
# integer into a string that is directly
the data_length = struct.pack ( 'I', length)
# stick package does not matter here, The client knows representative length of 4 bytes
conn.send (the data_length)
conn.send (cmd_res)

except Exception as e:
print(e)
break
```
客户端
```python
from socket import *
import struct
from functools import partial
ip_port=('127.0.0.1',8080)
back_log=5
buffer_size=1024

tcp_client=socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)

while True:
cmd=input('>>: ').strip()
if not cmd:continue
if cmd == 'quit':break

tcp_client.send(cmd.encode('utf-8'))


Solution viscosity packet #
# int type of data, binary standard length is 4, so the first four received
length_data = tcp_client.recv (4)
# take [0] is the first value, is resolved "int" type
length = struct. unpack ( 'i', length_data) [0]

= recv_msg '' the Join (ITER (partial (tcp_client.recv, buffer_size), B. ''))
# This is a problem for some, may be under study and research should be missing a Save function
# Analytical: 1.tcp_client.recv ( ) function receives the information, a maximum buffer_size bytes,
# using the partial function to tcp_client.recv () function is the first parameter buffer_size fixed
# 2 using ITER (), into the partial function iterables
# 3. memory acquiring each piece of data from the kernel mode, and spliced to 'until tcp_client.recv content B' '
Print ( "command execution result is', recv_msg.decode ( 'gbk') )

tcp_client.close ()
`` `
supplement: `
`` Python
#iter (Object, sentinel)
# write only one parameter: the first one becomes iterator
# add the second argument: sentinel, the sentinel iterative content immediately stop under

# Partial functions: a first function of fixed parameters
from functools Import partial
DEF add (X, Y):
return X + Y
# Specify the add function, add the first parameter passed to a
FUNC = partial (add, 1)
Print (FUNC (. 1)) # 2
Print (FUNC (. 1)). 3 #
`` `
Pack (FMT, V1, V2, ...) according to the given format (fmt), the data is encapsulated into a string (in fact, is similar to the structure of the byte stream c)
the unpack (FMT, String) byte stream parsing string, returns parsed according to a given format (fmt) tuple

socket in the sendall, based on the send (), is a dead cycle send, until all the data is sent.
And send a maximum of 8k (8096bytes) preferably, a maximum transmission unit MTU 1500 bytes card, sending too large, the data will fragment reassembly, to throw a distorted


** ** The subprocess
https://www.cnblogs.com/linhaifeng /articles/6129246.html#_label9

** ** avoid given communication cycle
1 at end of service conn.recv () a
use if empty: conn solution caused break off message server has received an empty endless loop
2. server in a communication cycle treatment client process is interrupted abnormally due to an error (forcibly closed by the remote host an existing connection)
the try:
# communication cycle
the except Exception AS E:
Print (E)
bREAK

transfer files - client uploaded to the server
`` ` Python
Import socket
Import os
Import json
Import struct

server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)

True the while:
Conn, addr = server.accept ()
the while True:
the try:
header_len conn.recv = (. 4)
# header parsing dictionary
header_len struct.unpack = ( 'I', header_len) [0]
# longer receive data dictionary
header_dic conn.recv = (header_len)
real_dic = json.loads (header_dic.decode ( 'UTF-. 8'))
# acquires data length
total_size = real_dic.get ( 'FILE_SIZE')
# loop receives and writes the file
recv_size = 0
with Open (real_dic.get ( 'file_name'), 'WB') AS F:
the while recv_size <total_size:
Data = conn.recv (1024)
f.write (Data)
recv_size + = len (Data)
Print ( "successful upload ')
AS E ConnectionResetError the except:
Print (E)
BREAK
Conn.close()
```

The client
`` `Python
Import socket
Import json
Import os
Import struct

client = socket.socket()
client.connect(('127.0.0.1',8080))

True the while:
# get movie listings cycle through
MOVIE_DIR = r'D: \ python full-time 10 video \ day25 \ video '
movie_list = os.listdir (MOVIE_DIR)
# Print (movie_list)
for i, Movie in the enumerate (movie_list, 1) :
Print (I, Movie)
# user selects
choice = INPUT ( 'Upload to >>> Please choice Movie:')
# determines whether a digital
iF choice.isdigit ():
# string into digital int
choice = int ( choice) -. 1
# determines whether the user selected is not within the list of ranges
IF choice in range (0, len (movie_list)):
# Get the user wants to upload a file path
path = movie_list [choice]
# splicing file absolute path
file_path = os .path.join (MOVIE_DIR, path)
# obtain the file size
FILE_SIZE = os.path.getsize (file_path)
# define a dictionary
res_d = {
'file_name': 'Sexy dealer online licensing .mp4',
'FILE_SIZE': FILE_SIZE,
'msg': 'attention to the body, drink plenty of Nutrition Express'
}
# serialization Dictionary
json_d = json.dumps (res_d)
json_bytes = json_d.encode ( 'utf-8')

# 1. First production dictionary format header
header struct.pack = ( 'I', len (json_bytes))
# 2. send dictionary header
client.send (header)
# 3. recurrent dictionary
client.send (json_bytes)
# 4. retransmission data file (file open loop transmission)
with open (file_path, 'RB') AS F:
for in Line F:
client.send (Line)
the else:
Print ( 'Not in Range')
the else:
Print ( ' Number BE A MUST ')
`` `

Guess you like

Origin www.cnblogs.com/lishuaing/p/11354060.html