TCP Based Socket:
####--------Service----------- import socket sk = socket.socket() #create a socket object sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #Reuse port sk.bind(("127.0.0.1",8105)) #Bind IP and port Numbers as tuples, AF_INET sk.listen() conn,addr = sk.accept() #block state,wait tcp connect,if sucess,return conn as socket new object,used to receive and send data while 1: ret = conn.recv(1024).decode("utf-8") #block state, until received a message from client print(ret) if ret == "bye": conn.send(b"bye") break else: new_send = input(">>>") conn.send(bytes(new_send,encoding = "utf-8")) conn.close() #close TCP connect sk.close() #close socket object,If not, continue receiving ####--------Client----------- import socket sk = socket.socket() sk.connect(("127.0.0.1",8105)) while 1: new_send = input(">>>") sk.send(bytes(new_send,encoding = 'utf-8')) #Data needs to be transmitted as bit new_recv = sk.recv(1024).decode("utf-8") print(new_recv) if new_recv == "bye": break sk.close()
注:print("你好".encode("utf-8")) == print(bytes("你好",encoding = "utf-8"))
UDP Based Socket
####--------Service----------- import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) sk.bind(("127.0.0.1",8889)) while 1: recv,addr = sk.recvfrom(1024) print(recv.decode("utf-8")) if recv.decode("utf-8") == "bye": break else: new_send = input(">>>>").encode("utf-8") sk.sendto(new_send,addr) sk.close() ####--------Client----------- import socket sk = socket.socket(type=socket.SOCK_DGRAM) ip_port = ("127.0.0.1",8889) while 1: new_send = input(">>>> ") if new_send == "bye": sk.sendto(new_send.encode("utf-8"),ip_prot) break else: new_send = "王: %s" %new_send sk.sendto(new_send.encode("utf-8"),ip_port) new_recv,addr= sk.recvfrom(1024) print(new_recv.decode("utf-8")) sk.close()
Tcp Sticky Package
The reason: TCP mechanism
Scenario: 1,Continuously send two small data --------The TCP optimization algorithm allows two send to be one send
2,Two recv ,The first one is small ------recv buffersize decide
Ex: The client to perform the shell command returns the results to the server
''' ####--------Service-----------### conn.recv(buffersize,flags) Receive up to buffersize bytes from the socket. For the optional flags argument, see the Unix manual. When no data is available, block until at least one byte is available or until the remote end is closed. When the remote end is closed and all data is read, return the empty string. ''' import socket sk = socket.socket() sk.bind(("127.0.0.1",8080)) sk.listen() conn,addr = sk.accept() while 1: cmd = input("input shell command>>> ").encode("gbk") if cmd == "q".encode("gbk"): new_send = conn.send("q".encode("gbk")) break else : new_send = conn.send(cmd) new_recv = conn.recv(1024).decode("gbk") print(new_recv) conn.close() sk.close() ####--------client----------### import socket import subprocess sk = socket.socket() sk.connect(("127.0.0.1",8080)) while 1: new_recv = sk.recv(1024).decode("gbk") if new_recv == "q": break else: ret = subprocess.Popen(new_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) #shell perform new_recv,Save the correct value to PIPE vessel and error value to PIPE vessel sk.send(ret.stdout.read()) sk.send(ret.stderr.read()) sk.close()
Sticky bag solution:Essence: the receiver does not know how much data to receive
First: add a connection so that the receiver knows the length of the sender's data
Cons:add a connection:If validation mechanism is not added, num and data may be stuck
####--------Service-----------### import socket sk = socket.socket() sk.bind(("127.0.0.1",8080)) sk.listen() conn,addr = sk.accept() while 1: cmd = input("input shell command>>> ").encode("gbk") if cmd == "q".encode("gbk"): new_send = conn.send("q".encode("gbk")) break else : new_send = conn.send(cmd) num = int(conn.recv(4096)) print(num) new_send = conn.send("ok".encode("utf-8")) new_recv = conn.recv(num).decode("gbk") print(new_recv) conn.close() sk.close() ####--------client----------### import socket import subprocess sk = socket.socket() sk.connect(("127.0.0.1",8080)) while 1: new_recv = sk.recv(1024).decode("gbk") if new_recv == "q": break else: ret = subprocess.Popen(new_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) stdout = ret.stdout.read() stderr = ret.stderr.read() new_send = sk.send(str(len(stdout)+len(stderr)).encode("utf-8")) new_ok = sk.recv(1024).decode("utf-8") if new_ok == "ok": sk.send(stdout) sk.send(stderr) sk.close()
Second:Through struct module, num is transformed into fixed byte to reduce connection.
####--------Service-----------### import socket import struct sk = socket.socket() sk.bind(("127.0.0.1",8080)) sk.listen() conn,addr = sk.accept() while 1: cmd = input("input shell command>>> ").encode("gbk") if cmd == "q".encode("gbk"): new_send = conn.send("q".encode("gbk")) break else : new_send = conn.send(cmd) num = conn.recv(4) num = struct.unpack("i",num)[0] new_recv = conn.recv(num).decode("gbk") print(new_recv) conn.close() sk.close() ####--------client----------### import socket import subprocess import struct sk = socket.socket() sk.connect(("127.0.0.1",8080)) while 1: new_recv = sk.recv(1024).decode("gbk") if new_recv == "q": break else: ret = subprocess.Popen(new_recv,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) stdout = ret.stdout.read() stderr = ret.stderr.read() num = len(stdout)+len(stderr) num = struct.pack("i",num) new_send = sk.send(num) sk.send(stdout) sk.send(stderr) sk.close()