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()
  • 相关阅读:
    gc buffer busy/gcs log flush sync与log file sync
    给Oracle年轻的初学者的几点建议
    Android 编程下帧动画在 Activity 启动时自动运行的几种方式
    Android 编程下 Touch 事件的分发和消费机制
    Java 编程下 static 关键字
    Java 编程下 final 关键字
    Android 编程下模拟 HOME 键效果
    Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated ?
    Extjs4 大型项目目录结构重构
    [转]SQLServer 2008 允许远程连接的配置方法
  • 原文地址:https://www.cnblogs.com/tsgxj/p/9445785.html
Copyright © 2011-2022 走看看