TCP 套叠字

一、  TCP 协议

       # ------------TCP套叠字--------------------

        server 端

import socket,time

ip_port=('localhost',51590)
bank_log=5
buffer_size=1024
tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 重用ip和端口解决time——wait状态(address already in use)
tcp_server.bind(ip_port)
tcp_server.listen(bank_log)
print("waiting for connet...")
while True:
    print("server working...")
    conn,addr = tcp_server.accept()
    print('server===>')
    print("双向链接是",conn)
    print("客户端地址",addr)
    while True:
        try:
            data=conn.recv(buffer_size)
            print("clent send message is :",data.decode("utf-8"))
            time.sleep(2)
            conn.sendall(data.upper())
        except Exception :
            print(Exception)
            break
    conn.close()
sk.close()

       TCP  客户端

import socket,time
ip_port=('localhost',1234)
bank_log=5
buffer_size=1024
tcp_clent = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_clent.connect(ip_port)
while True:
    msg = input("请输入字符串:>>>").strip()
    if not msg:continue
    tcp_clent.sendall(msg.encode("utf-8"))
    data = tcp_clent.recv(buffer_size)
    print("server send message is :",data.decode("utf8"))
tcp_clent.close()

二、UDP 协议

  '''tcp协议实现客户端输入的命令执行、服务端返回命令执行的结果'''

客户端:

'''TCP 协议实现:客户端发送命令’并接收服务端发送过来的消息'''
from socket import *
ip_port=('localhost',51590)
bank_log=5
buffer_size=1024
tcp_clent = socket(AF_INET,SOCK_STREAM)
tcp_clent.connect(ip_port)
while True:
    cmd = input("请输入字符串:>>>").strip()
    if not cmd:continue
    if cmd=="quit":break
    tcp_clent.send(cmd.encode("utf-8"))
    res_cmd = tcp_clent.recv(buffer_size)
    print("命令执行的结果是:",res_cmd.decode("gbk")) # 默认打开文件的编码为unicode默认编码是“gbk”
tcp_clent.close()

服务端(解决粘包):

  '''TCP 协议实现:客户端发送命令’服务端接收命令并把命令执行后的结果发送给客户端、
 从缓存区取数据时取的少了就出现粘包、下次取的还是上次烦的内容'''
'''tcp协议实现客户端输入的命令执行、将结果放到管道中、在管道中读取返回带客户端'''

import subprocess
from socket import *
ip_port = ("localhost", 51590)
buffer_size = 1024
back_log=5
tcp_server=socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
    print("waiting for connenct....")
    conn,addr=tcp_server.accept()
    print("双向链接是", conn)
    print("客户端地址", addr)
    while True:
        try:
            cmd = conn.recv(buffer_size)
            if not cmd:break
            print("收到客户端发送的消息是:",cmd)
            res = subprocess.Popen(cmd.decode("utf-8"),shell=True,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE)
            err=res.stderr.read()
            if err:
                cmd_res=err
            else:
                cmd_res=res.stdout.read()
            if not cmd_res:
                cmd_res="执行成功".encode("gbk")
            conn.send(cmd_res)
        except Exception:
            print(Exception)
            break
    conn.close()

三、UDP 协议粘包现象

 服务端:

'''UDP协议实现:客户端发送命令’服务端接收命令并把命令执行后的结果发送给客户端'''
import subprocess
from socket import *
ip_port = ("localhost", 51590)
buffer_size = 1024
back_log=5
udp_server=socket(AF_INET,SOCK_DGRAM)
udp_server.bind(ip_port)
while True:
    print("wait for send message...")
    cmd,addr = udp_server.recvfrom(buffer_size)
    print("收到客户端发送的消息是:",cmd)
    res = subprocess.Popen(cmd.decode("utf-8"), shell=True,
                           stderr=subprocess.PIPE,
                           stdin=subprocess.PIPE,
                           stdout=subprocess.PIPE)
    err = res.stderr.read()
    if err:
        cmd_res = err
    else:
        cmd_res = res.stdout.read()
    if not cmd_res:
        cmd_res = "执行成功".encode("gbk")
    udp_server.sendto(cmd_res,addr)
udp_server.close()

客户端:

import socket,time

ip_port=('localhost',51590)
bank_log=5
buffer_size=1024
tcp_server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 重用ip和端口解决time——wait状态(address already in use)
tcp_server.bind(ip_port)
tcp_server.listen(bank_log)
print("waiting for connet...")
while True:
    print("server working...")
    conn,addr = tcp_server.accept()
    print('server===>')
    print("双向链接是",conn)
    print("客户端地址",addr)
    while True:
        try:
            data=conn.recv(buffer_size)
            print("clent send message is :",data.decode("utf-8"))
            time.sleep(2)
            conn.sendall(data.upper())
        except Exception :
            print(Exception)
            break
    conn.close()
sk.close()

四、TCP   struct 模块解决粘包方法:

   服务端:

'''struct 解决粘包现象'''
'''tcp协议实现客户端输入的命令执行、服务端返回命令执行的结果'''
import struct,json
from socket import *
import subprocess
ip_port = ("localhost", 51590)
buffer_size = 1024
back_log = 5
tcp_server=socket(AF_INET,SOCK_STREAM)
tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
    print("waiting for connect...")
    conn,addr=tcp_server.accept()
    while True:
        try:
            cmd=conn.recv(buffer_size)
            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.decode("utf-8"))
            if err:
                back_msg = err
            else:
                back_msg = res.stdout.read()
            if not back_msg:
                back_msg="命令执行成功,".encode("utf-8")
            headers={'data_size':len(back_msg)}
            head_json=json.dumps(headers)
            head_json_bytes=bytes(head_json,encoding='utf-8')

            conn.send(struct.pack('i',len(head_json_bytes))) #先发报头的长度
            conn.send(head_json_bytes) #再发报头
            conn.sendall(back_msg) #在发真实的内容
        except Exception:
            print(Exception)
    conn.close()

  客户端:

'''struct 解决粘包现象'''
'''TCP 协议实现:客户端发送命令’并接收服务端发送过来的消息'''
from socket import *
import struct,json
ip_port=('localhost',51590)
buffer_size=1024
tcp_clent = socket(AF_INET,SOCK_STREAM)
tcp_clent.connect_ex(ip_port)
while True:
    msg = input("请输入字符串:>>>").strip()
    if not msg:continue
    if msg=="quit":break
    tcp_clent.send(msg.encode("utf-8"))
    try:
        heard = tcp_clent.recv(4)
        heard_json_len=struct.unpack("i",heard)[0]
        heard_json=json.loads(tcp_clent.recv(heard_json_len).decode("utf-8"))
        data_len=heard_json['data_size']
        recv_size=0
        recv_data=b''

        while recv_size<data_len:
            recv_data+=tcp_clent.recv(buffer_size)
            recv_size+=len(recv_data)
            print("命令执行的结果是:",recv_data.decode("gbk")) # 默认打开文件的编码为unicode默认编码是“gbk”
    except Exception:
        print(Exception)
tcp_clent.close()
原文地址:https://www.cnblogs.com/tsgxj/p/9445785.html