zoukankan      html  css  js  c++  java
  • 套接字

    1. 套接字通信循环

    # **********server.py*********
    import socket
    # 生成一个socket对象
    soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 绑定地址跟端口号
    soc.bind(('127.0.0.1',8000))
    # 监听(半连接池的大小)
    soc.listen(5)
    # 等着客户端来连接,conn相当于连接通道,addr是客户端的地址
    conn,addr = soc.accept()    # 卡住,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
    print(addr)
    while True:
        try:
            # 等待接收,最大收取1024个字节
            data = conn.recv(1024)   # 会卡住,当客户端有数据传过来,才会执行
            print(data)
        except Exception:
            # 关闭通道
            conn.close()
            break
    
    # 关闭套接字
    soc.close()
    
    
    # *********client.py********
    import socket
    
    soc = socket.socket()
    
    soc.connect(('127.0.0.1',8000))
    while True:
        inp_s = input('请输入要发送的数据:')
        # 发送的数据必须是b格式,inp_s.encode('utf-8') 把字符串编码成b格式
        # # 把b格式转成字符串
        # ss = str(b'hello',encoding='utf-8')
        # ss = b'hello'.decode('utf-8')
        # # 把字符串转成b格式
        # by = bytes('hello',encoding='utf-8')
        # by = 'hello'.encode('utf-8')
    
        soc.send(inp_s.encode('utf-8'))
    

    2. 套接字连接循环

    # **********server.py*********
    import socket
    # 生成一个socket对象
    soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 绑定地址跟端口号
    soc.bind(('127.0.0.1',8000))
    # 监听(半连接池的大小),不是连接数
    soc.listen(5)
    while True:
        # 等着客户端来连接,conn相当于连接通道,addr是客户端的地址
        print('等待客户端连接')
        conn,addr = soc.accept()    # 卡住,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
        print('已有客户连接:',addr)
        while True:
            try:
                # windows如果客户端断开,会报错,加了try
                # linux如果客户端,断开,不会报错,会收到空,所有当data为空时,也break
                # 等待接收,最大收取1024个字节
                data = conn.recv(1024)   # 会卡住,当客户端有数据传过来,才会执行
                if len(data) == 0:  #处理linux客户端断开,如果在window下这段代码根本不会执行(即便是客服端发了空,这个地方也不会走到)
                    break
                print(data)
            except Exception:
                break
        # 关闭通道
        conn.close()
    
    # 关闭套接字
    soc.close()
    
    
    
    # *********client.py*********
    import socket
    
    soc = socket.socket()
    
    soc.connect(('127.0.0.1',8000))
    while True:
        inp_s = input('请输入要发送的数据:')
        # 发送的数据必须是b格式,inp_s.encode('utf-8') 把字符串编码成b格式
        # # 把b格式转成字符串
        # ss = str(b'hello',encoding='utf-8')
        # ss = b'hello'.decode('utf-8')
        # # 把字符串转成b格式
        # by = bytes('hello',encoding='utf-8')
        # by = 'hello'.encode('utf-8')
    
        soc.send(inp_s.encode('utf-8'))
    

    3. 模拟ssh功能

    # ******subprocess.py*******
    
    #ssh 是远程执行命令
    #subprocess 执行系统命令的模块
    import subprocess
    #执行系统dir命令,把执行的正确结果放到管道中
    # obj=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
    obj=subprocess.Popen('tasklistdd',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    #拿到正确结果的管道,读出里面的内容
    ss=obj.stdout.read()
    err=obj.stderr.read()
    print('错误信息',str(err,encoding='gbk'))
    #因为windows用的gbk编码,用gbk解码
    # print(str(ss,encoding='utf-8'))
    print(str(ss,encoding='gbk'))
    
    
    # ********server.py********
    import socket
    import subprocess
    soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1',8001))
    soc.listen(3)
    while True:
        print('等待客户端连接')
        conn,addr=soc.accept()
        print('有个客户端连接上了',addr)
        while True:
            try:
                data=conn.recv(1024)
                if len(data)==0:
                    break
                print(data)
                obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                #执行正确的结果 b 格式,gbk编码(windows平台)
                msg=obj.stdout.read()
                #把执行的结果通过网络传给c端
                conn.send(msg)
            except Exception:
    
                break
        # 关闭通道
        conn.close()
    
    # 关闭套接字
    soc.close()
    
    
    # *******client.py*********
    import socket
    
    soc=socket.socket()
    
    soc.connect(('127.0.0.1',8001))
    while True:
        in_s=input('请输入要执行的命令:')
        soc.send(in_s.encode('utf-8'))
        data=soc.recv(1024)
        print(str(data,encoding='gbk'))
    
    
    #粘包:tcp会把数据量较小,时间间隔较短的数据,当做同一个包发送
    

    4. 粘包问题

    # *******server.py*********
    import socket
    #生成一个socket对象
    soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #绑定地址跟端口号
    soc.bind(('127.0.0.1',8001))
    #监听(半连接池的大小),不是连接数
    soc.listen(3)
    #等着客户端来连接,conn相当于连接通道,addr是客户端的地址
    while True:
        print('等待客户端连接')
        conn,addr=soc.accept()    #卡主,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
        print('有个客户端连接上了',addr)
        while True:
            try:
                data=conn.recv(1024)
                print(data)
                data2=conn.recv(1024)
                print(data2)
                data3=conn.recv(1024)
                print(data3)
            except Exception:
    
                break
        # 关闭通道
        conn.close()
    
    # 关闭套接字
    soc.close()
    
    
    # ********client.py********
    import socket
    
    soc=socket.socket()
    
    soc.connect(('127.0.0.1',8001))
    while True:
        in_s=input('请输入要发送的数据:')
        soc.send(b'a')
        soc.send(b'b')
        soc.send(b'c')
    

    5. 解决粘包问题

    # ********struct模块********
    import struct
    #把一个数字打包成固定长度的4字节
    obj=struct.pack('i',1098)
    print(obj)
    print(len(obj))
    
    l=struct.unpack('i',obj)[0]
    print(l)
    
    
    # ********server.py*********
    import socket
    import subprocess
    import struct
    soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1',8001))
    soc.listen(3)
    while True:
        print('等待客户端连接')
        conn,addr=soc.accept()
        print('有个客户端连接上了',addr)
        while True:
            try:
                data=conn.recv(1024)
                if len(data)==0:
                    break
                print(data)
                obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                #执行正确的结果 b 格式,gbk编码(windows平台)
                msg=obj.stdout.read()
                #发送的时候需要先把长度计算出来
                #头必须是固定长度
                #10
                #100
                #先取出要发送数据长度l
    
                l=len(msg)
                #head 是固定四个字节
                head=struct.pack('i',l)
                #发了头
                conn.send(head)
                #发了内容
                conn.send(msg)
            except Exception:
    
                break
        # 关闭通道
        conn.close()
    
    
    # 关闭套接字
    soc.close()
    
    
    # ********client.py********
    import socket
    import struct
    soc=socket.socket()
    
    soc.connect(('127.0.0.1',8001))
    while True:
        in_s=input('请输入要执行的命令:')
        soc.send(in_s.encode('utf-8'))
        head=soc.recv(4)
        l=struct.unpack('i',head)[0]
        # data=soc.recv(l)
        count=0
        data_total=b''
    
        while count<l:
            if l<1024: #如果接受的数据小于1024 ,直接接受数据大小
                data=soc.recv(l)
            else:#如果接受的数据大于1024
                if l-count>=1024: #总数据长度-count(目前收到多少,count就是多少) 如果还大于1024  ,在收1024
                    data=soc.recv(1024)
                else: #总数据长度-count(目前收到多少,count就是多少) 如果小于1024,只收剩下的部分就可
                    data=soc.recv(l-count)
    
            data_total+=data
            count+=len(data)
    
        print(str(data_total,encoding='gbk'))
    

    6. 解决粘包问题终极版

    # ********struct模块*********
    
    import struct
    import json
    import struct
    
    head={'size':100999999999999999999999990000000000000000000000000000000000000000,'md5':'sdfsdfasdf','filename':'a.txt'}
    head_str=json.dumps(head)
    head_bytes=head_str.encode('utf-8')
    print(len(head_bytes))
    obj=struct.pack('i',len(head_bytes))
    print(obj)
    print(len(obj))
    
    #发
    send(obj)
    send(head_bytes)
    send(b'ddddddddddddddddddd')
    #收
    obj=recv(4)
    head_len=struct.unpack('i',obj)[0]
    head_bytes=recv(head_len)
    
    head_dic=json.loads(head_bytes)
    l=head_dic['size']
    
    
    # *******server.py**********
    import socket
    import subprocess
    import struct
    soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1',8001))
    soc.listen(3)
    while True:
        print('等待客户端连接')
        conn,addr=soc.accept()
        print('有个客户端连接上了',addr)
        while True:
            try:
                data=conn.recv(1024)
                if len(data)==0:
                    break
                print(data)
                obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                #执行正确的结果 b 格式,gbk编码(windows平台)
                msg=obj.stdout.read()
    
                #发送的时候需要先把长度计算出来
                #头必须是固定长度
                #先发4位,头的长度
                import json
                dic={'size':len(msg)}
                dic_bytes=(json.dumps(dic)).encode('utf-8')
                #head_count是4个字节的长度
                head_count=struct.pack('i',len(dic_bytes))
                print(dic)
                conn.send(head_count)
                #发送头部内容
                conn.send(dic_bytes)
                #发了内容
                conn.send(msg)
            except Exception:
    
                break
        # 关闭通道
        conn.close()
    
    
    # 关闭套接字
    soc.close()
    
    
    # ********client.py*********
    import socket
    import struct
    import json
    soc=socket.socket()
    
    soc.connect(('127.0.0.1',8001))
    while True:
        in_s=input('请输入要执行的命令:')
        soc.send(in_s.encode('utf-8'))
        #头部字典的长度
        head_dic_len=soc.recv(4)
        #解出真正的长度
        head_l=struct.unpack('i',head_dic_len)[0]
        #byte 字典的长度
        #收真正的头部字典
        dic_byte=soc.recv(head_l)
        head=json.loads(dic_byte)
        print(head)
        l=head['size']
        count=0
        data_total=b''
        print(l)
        while count<l:
            if l<1024: #如果接受的数据小于1024 ,直接接受数据大小
                data=soc.recv(l)
            else:#如果接受的数据大于1024
                if l-count>=1024: #总数据长度-count(目前收到多少,count就是多少) 如果还大于1024  ,在收1024
                    data=soc.recv(1024)
                else: #总数据长度-count(目前收到多少,count就是多少) 如果小于1024,只收剩下的部分就可
                    data=soc.recv(l-count)
    
            data_total+=data
            count+=len(data)
    
        print(str(data_total,encoding='gbk'))
    
  • 相关阅读:
    互斥锁和条件变量实现生产者消费者问题
    信号量实现生产者消费者问题
    IPC进程间通信---共享内存
    IPC进程间通信---消息队列
    图的遍历---广度优先遍历和深度优先遍历
    图的两种存储方式---邻接矩阵和邻接表
    内存分配---FF、BF、WF三种算法
    C++的前置++、后置++和前置--、后置--
    IPC进程间通信---信号量
    Linux进程间通信---管道和有名管道
  • 原文地址:https://www.cnblogs.com/yushan1/p/11475687.html
Copyright © 2011-2022 走看看