zoukankan      html  css  js  c++  java
  • Day 网络协议介绍 简单通信的实现

    比如说实现两个手机之间的通信,需要做的几部:

    服务端:

    1,买手机

    2,插卡

    3,开机

    4,等电话链接

    5,基于建立的链接,收发协议

    6,挂电话

    7,关机

    import socket
    #买手机
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #插卡
    phone.bind(('127.0.0.1',8080))
    #开机
    phone.listen(5)
    #等电话链接
    print('server start...')
    conn,client_addr=phone.accept() #(tcp链接,client_addr)
    print('链接',conn)
    print(client_addr)
    
    #基于建立的链接,收发消息
    client_data=conn.recv(1024)
    print('客户端的消息',client_data)
    conn.send(client_data.upper())
    
    #挂电话链接
    conn.close()
    
    #关机
    phone.close()

    客户端:

    import socket
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    
    
    phone.send('hello'.encode('utf-8'))
    server_data=phone.recv(1024)
    print('服务端回应的消息',server_data)
    
    phone.close()

    加上通信循环与链接循环:

    服务端:

     1 import socket
     2 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     3 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
     4 phone.bind(('127.0.0.1',8080))
     5 phone.listen(5)
     6 print('server start...')
     7 conn,client_addr=phone.accept()
     8 
     9 while True: #通讯循环
    10     client_data=conn.recv(1024)
    11     # print('has rev')
    12     conn.send(client_data.upper())
    13 
    14 conn.close()
    15 
    16 phone.close()
    View Code

    客户端:

     1 import socket
     2 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     3 phone.connect(('127.0.0.1',8080))
     4 
     5 while True:
     6     msg=input('>>: ').strip()
     7     if not msg:continue
     8     phone.send(msg.encode('utf-8'))
     9     # print('====>has send')
    10     server_data=phone.recv(1024)
    11     # print('====>has recv')
    12     print(server_data.decode('utf-8'))
    13 
    14 phone.close()
    View Code

    解决粘包现象:

    服务端:

     1 import socket
     2 import struct
     3 import subprocess
     4 import json
     5 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     6 phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
     7 phone.bind(('127.0.0.1',8080))
     8 phone.listen(5)
     9 print('server start...')
    10 while True: #链接循环
    11     conn,client_addr=phone.accept()
    12     print(conn,client_addr)
    13 
    14     while True: #通讯循环
    15         try:
    16             cmd=conn.recv(1024)
    17             if not cmd:break
    18 
    19             #执行命令,拿到结果
    20             res=subprocess.Popen(cmd.decode('utf-8'),
    21                              shell=True,
    22                              stdout=subprocess.PIPE,
    23                              stderr=subprocess.PIPE)
    24 
    25             stdout=res.stdout.read()
    26             stderr=res.stderr.read()
    27 
    28 
    29             #制作报头
    30             header_dic={'total_size':len(stdout)+len(stderr),'md5':None}
    31             header_json=json.dumps(header_dic)
    32             header_bytes=header_json.encode('utf-8')
    33 
    34 
    35             #1 先发报头的长度(固定4个bytes)
    36             conn.send(struct.pack('i',len(header_bytes)))
    37 
    38 
    39             #2 先发报头
    40             conn.send(header_bytes)
    41 
    42 
    43             #3 再发真实的数据
    44             conn.send(stdout)
    45             conn.send(stderr)
    46 
    47         except Exception: #针对windwos
    48             break
    49     conn.close()
    50 
    51 phone.close()

    客户端:

     1 import socket
     2 import struct
     3 import json
     4 phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
     5 phone.connect(('127.0.0.1',8080))
     6 
     7 while True:
     8     cmd=input('>>: ').strip()
     9     if not cmd:continue
    10     #发命令
    11     phone.send(cmd.encode('utf-8'))
    12 
    13 
    14     #先收报头的长度
    15     struct_res=phone.recv(4)
    16     header_size=struct.unpack('i',struct_res)[0]
    17 
    18     #再收报头
    19     header_bytes=phone.recv(header_size)
    20     head_json=header_bytes.decode('utf-8')
    21     head_dic=json.loads(head_json)
    22 
    23     total_size=head_dic['total_size']
    24     #再收命令的执行结果
    25     recv_size=0
    26     data=b''
    27     while recv_size < total_size:
    28         recv_data=phone.recv(1024)
    29         recv_size+=len(recv_data)
    30         data+=recv_data
    31 
    32     #打印结果
    33     print(data.decode('gbk'))
    34 
    35 phone.close()

    实现并发的代码:

    服务端:

     1 import socketserver
     2 class MyTcphandler(socketserver.BaseRequestHandler):
     3     def handle(self):
     4         while True: #通信循环
     5             data=self.request.recv(1024)
     6             self.request.send(data.upper())
     7 if __name__ == '__main__':
     8     #取代链接循环
     9     server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyTcphandler)
    10     server.serve_forever()

    客户端:

    import socket
    phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    phone.connect(('127.0.0.1',8080))
    
    while True:
        msg=input('>>: ').strip()
        if not msg:continue
        phone.send(msg.encode('utf-8'))
        server_data=phone.recv(1024)
        print(server_data.decode('utf-8'))
    
    phone.close()
  • 相关阅读:
    你看,那个人好像一条狗哎
    我竟然被抓去做了比特币挖矿工
    聊聊JAVA中 String类为什么不可变
    三分钟深入TT猫之故障转移
    shell实现两个数的相加
    shell截取字符串的方法
    Vi命令:如何删除全部内容?
    bash中不可以用字符串做数组下标
    awk打印出当前行的上一行
    awk同时处理多个文件
  • 原文地址:https://www.cnblogs.com/sexiaoshuai/p/7420986.html
Copyright © 2011-2022 走看看