zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    多线程与Socket编程
    正则表达式
    委托事件泛型
    C#基础加强
    随笔
    不设置JAVA_HOME运行eclipse
    CentOS7.x系统中使用Docker时,在存储方面需要注意的问题
    【转】关于高可用负载均衡的探索-基于Rancher和Traefic
    Rancher 容器管理平台-免费视频培训-链接及内容-第三季
    使用Rancher的RKE快速部署Kubernetes集群
  • 原文地址:https://www.cnblogs.com/tsgxj/p/9445785.html
Copyright © 2011-2022 走看看