C / S structure (client / server architecture), divided into hardware C / S structure (printer) and software C / S architecture.
Internet protocol according to different functions into seven or osi tcp / ip five or tcp / ip four
Common physical device layers
ip (where to find the local area network) + mac (find the physical host) + port (find application) binding the target application can be found on the target device.
PID program: to identify different processes on the same machine or threads.
Socket Works
Start talking about the server side. Server initialized Socket, then the port binding (bind), listens to port (listen), call accept blocks, waiting for client connections. At this point if you have a client initiates a Socket, then connect to the server (connect), if the connection is successful, then connect the client and the server is established. The client sends a data request, the server receives the request and processes the request, and then sends the response data to the client, the client reads the data, and finally close the connection, ends of an interaction.
Impersonating the client and server interaction
Client
#_*_coding:utf-8_*_ __author__ = 'Linhaifeng' import socket ip_port=('127.0.0.1',9000) BUFSIZE=1024 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect_ex (ip_port) # connected to the address s.send ( 'linhaifeng nb'.encode (' utf-8 ')) # message, encoding feedback = s.recv (BUFSIZE) # received message print(feedback.decode('utf-8')) s.close () # exit
Server
# -*- coding: utf-8 -*- import socket ip_port = ( '127.0.0.1', 9000) # communication address BUFSIZE = size of messaging # 1024 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) # address family and communication protocol family s.bind (ip_port) # bind address s.listen (5) # can accept up to five conn, addr = s.accept () # accept message Wait # print(conn) # print(addr) print ( 'receiving telephone from% s'% addr [0]) msg = conn.recv (BUFSIZE) # to listen to the message, obedient print(msg,type(msg)) conn.send (msg.upper ()) # Message conn.close () # shutdown process s.close () # exit
Run the client, enter information in the service side, you can see
Four-way handshake broken link above two lines (client-initiated) for Active disconnected, the following two (server initiated) represents the passive disconnected.
Since the beginning there is no data connection is established, the client and the server response to a client can initiate a request and together. However, when disconnected, there may upload or download data, it can not be combined.
The client receives information cycle
Client
#_*_coding:utf-8_*_ __author__ = 'Linhaifeng' import socket ip_port=('127.0.0.1',9000) BUFSIZE=1024 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect_ex (ip_port) # connected to the address while True: msg = input ( 'Enter:') s.send (msg.encode ( 'utf-8')) # message, encoding feedback = s.recv (BUFSIZE) # received message print(feedback.decode('utf-8')) s.close () # exit
Server
# -*- coding: utf-8 -*- import socket ip_port = ( '127.0.0.1', 9000) # communication address BUFSIZE = size of messaging # 1024 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) # address family and communication protocol family s.bind (ip_port) # bind address s.listen (5) # can accept up to five conn, addr = s.accept () # accept message Wait # print(conn) # print(addr) print ( 'receiving telephone from% s'% addr [0]) while True: msg = conn.recv (BUFSIZE) # to listen to the message, obedient print ( 'message received from the client', msg) conn.send (msg.upper ()) # Message conn.close () # shutdown process s.close () # exit
conn is a socket object
Server cycles to provide services
Client
#_*_coding:utf-8_*_ import socket ip_port=('127.0.0.1',9000) BUFSIZE=1024 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s.connect_ex (ip_port) # connected to the address while True: msg = input ( 'Enter:') if not msg: continue # Enter not only to solve the case of data stuck s.send (msg.encode ( 'utf-8')) # message, encoding feedback = s.recv (BUFSIZE) # received message print(feedback.decode('utf-8')) s.close () # exit
Server
# -*- coding: utf-8 -*- import socket ip_port = ( '127.0.0.1', 9000) # communication address BUFSIZE = size of messaging # 1024 s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) # address family and communication protocol family s.bind (ip_port) # bind address s.listen (5) # can accept up to five while True: # and a plurality of user communication conn, addr = s.accept () # accept message Wait # print(conn) # print(addr) print ( 'receiving telephone from% s'% addr [0]) while True: # cycle to receive information try: msg = conn.recv (BUFSIZE) # to listen to the message, obedient print ( 'message received from the client', msg) conn.send (msg.upper ()) # Message except Exception: break conn.close () # shutdown process s.close () # exit
udp socket
udp no three-way handshake and the four-way handshake, so not listening
Client
#_*_coding:utf-8_*_ import socket ip_port=('127.0.0.1',9000) BUFSIZE=1024 udp_server_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) while True: # do cycle message msg=input('>>: ').strip() if not msg: continue # Enter not only to solve the case of data stuck udp_server_client.sendto (msg.encode ( 'utf-8'), ip_port) # hair and port information content back_msg, addr = udp_server_client.recvfrom (BUFSIZE) # message received and the address print(back_msg.decode('utf-8'),addr)
Server
# -*- coding: utf-8 -*- import socket ip_port = ( '127.0.0.1', 9000) # address and port BUFSIZE = 1024 # bytes udp_server_client=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) udp_server_client.bind (ip_port) # port binding while True: msg, addr = udp_server_client.recvfrom (BUFSIZE) # accept message and address print(msg,addr) udp_server_client.sendto (msg.upper (), addr) # message and address
Time Server
Client
#_*_coding:utf-8_*_ from socket import * ip_port=('127.0.0.1',9000) bufsize=1024 tcp_client = socket (AF_INET, SOCK_DGRAM) while True: msg = input ( 'Enter time format (Example% Y% m% d) >>:') .strip () tcp_client.sendto(msg.encode('utf-8'),ip_port) data=tcp_client.recv(bufsize) print(data.decode('utf-8')) tcp_client.close()
Server
# -*- coding: utf-8 -*- from socket import * from time import strftime ip_port = ('127.0.0.1', 9000) bufsize = 1024 tcp_server = socket (AF_INET, SOCK_DGRAM) tcp_server.bind(ip_port) while True: msg, addr = tcp_server.recvfrom(bufsize) print('===>', msg) if not msg: time_fmt = '%Y-%m-%d %X' else: time_fmt = msg.decode('utf-8') back_msg = strftime(time_fmt) tcp_server.sendto(back_msg.encode('utf-8'), addr) tcp_server.close()
TCP-based remote command execution
Server
# -*- coding: utf-8 -*- from socket import * import subprocess ip_port = ('127.0.0.1', 9000) back_log=5 buffer_size = 1024 tcp_server = socket (AF_INET, SOCK_STREAM) tcp_server.bind(ip_port) tcp_server.listen(back_log) while True: conn,addr = tcp_server.accept() print ( 'new client connection ===>', addr) while True: try: # abort processing cmd=conn.recv(buffer_size) print ( 'client connections ===>', cmd) # Execute command cmd res=subprocess.Popen(cmd.decode('utf-8'),shell=True,stderr=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE) err=res.stdout.read() if err: # judgment result cmd_res=err else: cmd_res=res.stdout.read() conn.send(cmd_res) except Exception as e: print (e) break conn.close() # tcp_server.close()
Client
#_*_coding:utf-8_*_ from socket import * ip_port = ('127.0.0.1', 9000) back_log=5 buffer_size = 1024 tcp_client = socket (AF_INET, SOCK_STREAM) tcp_client.connect(ip_port) while True: cmd = input ( 'Enter command cmd "" "') .strip () if not cmd: continue # handle input is empty if cmd=='quit':break tcp_client.send(cmd.encode('utf-8')) cmd_res=tcp_client.recv(buffer_size) print ( 'command execution result', cmd_res.decode ( 'gbk')) tcp_client.close()
Above can not be done concurrently, you can only build a pair of connectors.
Windows environment, res.stdout.read () is read out encoding GBK, the receiving end decodes need GBK
Stick package (since acquired content exceeds the buffer, when executing the next command, the system reads the contents of the last command is still not finished reading)
Problems stick package mainly because the receiver does not know the limits between the message, does not know how many bytes of data caused by the time extraction.
Only TCP packet sticky phenomenon, UDP never stick package (udp received only once, do not charge throw).
TCP is a byte stream (without header), UDP is a message flow (with headers)
Solution TCP stick package problems: the header made dictionary, the dictionary contains details real data to be transmitted, then json serialization, then packed into a 4-byte data length after the struck serialized (4 themselves sufficient used)
Sent when:
First transmitter head length
Re-encoding the header and then transmits the content
Finally, the true content of hair
Receives:
Sente header length, taken out with struct
The content length header charged removed, then decoded, deserialized
Details of data to be taken out from the take deserialize the results and real data fetch content
Service-side implementation
# -*- coding: utf-8 -*- import socket,struct,json import subprocess phone = socket.socket (socket.AF_INET, socket.SOCK_STREAM) phone.setsockopt (socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # is it, added before bind phone.bind(('127.0.0.1',8080)) phone.listen(5) while True: conn,addr=phone.accept() while True: cmd=conn.recv(1024) if not cmd:break print('cmd: %s' %cmd) res=subprocess.Popen(cmd.decode('utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) err=res.stderr.read() print(err) if err: back_msg=err else: back_msg=res.stdout.read() #change conn.send (struct.pack ( 'i', len (back_msg))) # starting length back_msg conn.sendall (back_msg) # fat content in real conn.close()
Client implementation
#_*_coding:utf-8_*_ import socket,time,struct s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) res=s.connect_ex(('127.0.0.1',8080)) while True: msg=input('>>: ').strip() if len(msg) == 0:continue if msg == 'quit':break s.send(msg.encode('utf-8')) #change l=s.recv(4) # Acquires a received content size x=struct.unpack('i',l)[0] print(type(x),x) # print(struct.unpack('I',l)) r_s=0 data=b'' while r_s < x: r_d=s.recv(1024) data+=r_d r_s + = len (r_d) # print(data.decode('utf-8')) print (data.decode ( 'gbk')) #windows default encoding gbk