# 1. Enter a command with a shorter result, such as Dir # 2. Enter a command with a longer result arp-a #观察TCP黏包现象!!!
#server. PY Import Socket SK = Socket.socket () sk.bind ((' 127.0.0.1 ', 9000)) Sk.listen () conn,addr = Sk.accept () while True: cmd = input (' >>> ') conn.send (Cmd.encode (' Utf-8 ')) #1. Server-side input command, sent to client, if cmd = = ' Q ': BR Eak Ret1 = CONN.RECV (1024) #8. This step and the next can happen sticky bag, why? Dir results are not analyzed, print (' stdout: ', Ret1.decode
(' GBK ')) Ret2 = CONN.RECV (1024) #9. Arp-a execution result is longer, RET1 can not be received, so will be Ret2 received, print (' stderr: ', Ret2.decode (' G BK ') #所以打印ret2会显示本该在ret1中显示的信息, Conn.close () sk.close () # client.py import socket import subprocess SK = Socket.s Ocket () sk.connect (' 127.0.0.1 ', 9000) while true:cmd = SK.RECV (1024). Decode (' Utf-8 ') print (cmd) #2. Receive the command from the server, and print out if cmd = = ' Q ': Break ret = subprocess. Popen (Cmd,shell=true, #3.) Here is the execution of our order, even if the wrong command will have the output, Stdout=subproCess. PIPE, Stderr=subprocess. PIPE) out = Ret.stdout.read () #4. If the command has output, it will be saved here Err = Ret.stderr.read () #5. If the command has an error message, it will be saved here print (out, ' *****\n ', err) #6. This will be complete!!! Print execution results, but it also means that the results of popen () do not require our manual encoding, sk.send (b ' out: ' +out ') sk.send (b ' ERROR: ' +err) #7. These two sentences send the results of our execution to the server, Sk.close () #print (' Out: ', Ret.stdout.read ()). Decode (' GBK ') #print (' Err: ', Ret.stderr.read () . Decode (' GBK '))
#UDP的 "Sticky Package" features, note that UDP is not a sticky bag!!! #server. py #_ *_coding:utf-8_*_ from socket import * Import subprocess ip_port= (' 127.0.0.1 ', 9000) bufsize=1024 Udp_server =socket (Af_inet,sock_dgram) udp_server.setsockopt (sol_socket,so_reuseaddr,1) Udp_server.bind (ip_port) while True: # Receiving message Cmd,addr=udp_server.recvfrom (bufsize) #2. Receive the client's command, print (' User command-----> ', cmd) #逻辑处理 res=sub Process. Popen (Cmd.decode (' Utf-8 '), shell=true,stderr=subprocess. Pipe,stdin=subprocess. Pipe,stdout=subprocess. PIPE) Stderr=res.stderr.read () Stdout=res.stdout.read () #3. Execute the command to save the results #发消息 Udp_serv Er.sendto (STDERR,ADDR) udp_server.sendto (STDOUT,ADDR) #4. Sends command execution results to the client, Udp_server.close () #clien
t.py from Socket Import * ip_port= (' 127.0.0.1 ', 9000) bufsize=1024 #修改这个参数为4096或更大来看现象 Udp_client=socket (Af_inet,sock_dgram) while True:msg=input (' >>: '). Strip () Udp_client.sendto (Msg.encode (' U Tf-8 '), Ip_porT) #1. Enter a command to send to the server side, Err,addr=udp_client.recvfrom (bufsize) out,addr=udp_client.recvfrom (bufsize)
#5, receive the execution result of the command if err: #6, print the execution result of the command. Print (' ERROR:%s '%err.decode (' GBK '), end= ') if Out:print (Out.decode (' GBK '), end= ') #TCP是基于连接的, stream, unbounded cannot differentiate between numbers
According to the separation, #对于短消息, the default will not send empty or too short information, but will gather enough to send a quantity, but not to say that too long, can not wait until tomorrow? #对于长消息, although there is no boundary, but the receiver or the sender's buffer is limited, #由于传输层无法区分应用层数据的边界或分隔, so will occur #TCP的这个特点, and the MTU and kernel State optimization, #对于UDP, #非流的, packet-oriented, A packet of information, so there is no sticky packets between packages, #即使是空的数据也会当做一个数据包发送出去, #由于是面向数据包的, so when the packet sent is greater than the recvfrom () receive buffer, the packet will not be split, but will be directly error: #错误信息
: OSError: [Winerror 10040] A message sent on a datagram socket is larger than the internal message buffer or some other network restrictions, or the buffer used by the user to receive datagrams is smaller than the datagram. #由于UDP是面向数据包的, so send and receive operation need one by one corresponding, otherwise will be lost packet,
#server. py
#_ *_coding:utf-8_*_
from socket import *
ip_port= (' 127.0.0.1 ', 8080)
tcp_socket_server= Socket (Af_inet,sock_stream)
tcp_socket_server.bind (ip_port)
Tcp_socket_server.listen (5)
conn,addr= Tcp_socket_server.accept ()
data1=conn.recv
print ('-----> ', data1.decode (' Utf-8 ')
data2= CONN.RECV # conn never receive empty data, conn when disconnected recv receive an empty
#!!! We all know that TCP does not send empty data, so it's supposed to print something, but if the remote is closed, it's forced to receive an empty one.
Print ('-----> ', Len (data2), Data2.decode (' Utf-8 '))
conn.close ()
tcp_socket_server.close ()
# client.py
#_ *_coding:utf-8_*_
import socket
bufsize=1024
ip_port= (' 127.0.0.1 ', 8080)
s= Socket.socket (Socket.af_inet,socket. SOCK_STREAM)
res=s.connect_ex (ip_port)
s.send (' Hello '. Encode (' Utf-8 ')) # s.send (' egg '
. Encode (') Utf-8 '))
import Time
time.sleep (5)
s.close ()
#TCP黏包问题之, the buffer size.
#server. py
from socket import *
ip_port= (' 127.0.0.1 ', 8080)
Tcp_socket_server=socket (af_inet,sock_ STREAM)
tcp_socket_server.bind (ip_port)
Tcp_socket_server.listen (5)
conn,addr=tcp_socket_ Server.accept ()
data1=conn.recv (2) #下面打印的he, which is related to the 2 here,
data2=conn.recv
print ('-----> ', Data1.decode (' utf-8 ')
print ('-----> ', data2.decode (' Utf-8 '))
#打印结果:
#-----> He
#----- > Lloegg
conn.close ()
tcp_socket_server.close ()
#client. py
#_ *_coding:utf-8_*_
Import Socket
bufsize=1024
ip_port= (' 127.0.0.1 ', 8080)
S=socket.socket (socket.af_inet,socket. SOCK_STREAM)
res=s.connect_ex (ip_port)
s.send (' Hello '. Encode (' Utf-8 ')) s.send (' egg '
. Encode) (' Utf-8 '))
S.close ()
#使用struct的pack和unpack来解决问题,
#server. py
Import struct
import socket
SK = Socket.socket ()
Sk.bind ((' 127.0.0.1 ', 9000))
Sk.listen ()
conn,addr = Sk.accept () while
True:
ret = CONN.RECV (4)
Print (Struct.unpack (' I ', ret)), Struct.unpack (' I ', ret))
length = Struct.unpack (' i ', ret) [0] #unpack ( The result is a tuple, so use [0] to take
msg = conn.recv (length)
print (Msg.decode (' Utf-8 '))
conn.close ()
#打印结果:
# 1,) #这里异常, is not our socket transmission frequently causes the buffer to flush???
# Hello World
# <class ' tuple ' > (one,)
# Hello World
#client. PY
Import Socket
Import struct
SK = Socket.socket ()
sk.connect (' 127.0.0.1 ', 9000)) while
True:
msg = ' Hello World '
Length = Struct.pack (' i ', Len (msg)) #i代表用4字节固定长度存储, large enough,
sk.send (length)
sk.send (Msg.encode (' Utf-8 '))
Sk.close ()
#这是一个小文件发送的综合例子, there's nothing to say. Import
OS
import JSON
import struct
import socket
SK = Socket.socket ()
Sk.bind ((' 127.0.0.1 ', 9000))
Sk.listen ()
conn,addr = sk.accept ()
print (addr)
dic = {' filename ' : ' BugReport.txt ',
' filesize ': os.path.getsize (R ' E:\BugReport.txt ')}
str_dic = Json.dumps (DIC). Encode (' Utf-8 ') #字典不能直接在网络上发送, so first serialize,
Dic_len = struct.pack (' i ', Len (str_dic))
conn.send (Dic_len)
Conn.send (str_dic)
with open (R ' E:\BugReport.txt ', ' RB ') as f:
content = F.read ()
conn.send (content)
conn.close ()
sk.close ()
#client. PY
Import JSON import
struct
import socket
SK = Socket.socket ()
sk.connect (' 127.0.0.1 ', 9000))
Dic_len = SK.RECV (4)
Dic_len = Struct.unpack (' i ', Dic_len) [0]
str_dic = SK.RECV (Dic_len). Decode (' Utf-8 ')
dic = Json.loads (str_dic) with
open (dic[' FileName '], ' WB ' as f:
content = sk.recv (dic[' filesize '])
f.write (content)
Sk.close ()