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()
原文地址:https://www.cnblogs.com/sexiaoshuai/p/7420986.html