比如说实现两个手机之间的通信,需要做的几部:
服务端:
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()
加上通信循环与链接循环:
服务端:
import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('server start...')
conn,client_addr=phone.accept() while True: #通讯循环
client_data=conn.recv(1024)
# print('has rev')
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)) while True:
msg=input('>>: ').strip()
if not msg:continue
phone.send(msg.encode('utf-8'))
# print('====>has send')
server_data=phone.recv(1024)
# print('====>has recv')
print(server_data.decode('utf-8')) phone.close()
解决粘包现象:
服务端:
import socket
import struct
import subprocess
import json
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))
phone.listen(5)
print('server start...')
while True: #链接循环
conn,client_addr=phone.accept()
print(conn,client_addr) while True: #通讯循环
try:
cmd=conn.recv(1024)
if not cmd:break #执行命令,拿到结果
res=subprocess.Popen(cmd.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE) stdout=res.stdout.read()
stderr=res.stderr.read() #制作报头
header_dic={'total_size':len(stdout)+len(stderr),'md5':None}
header_json=json.dumps(header_dic)
header_bytes=header_json.encode('utf-8') #1 先发报头的长度(固定4个bytes)
conn.send(struct.pack('i',len(header_bytes))) #2 先发报头
conn.send(header_bytes) #3 再发真实的数据
conn.send(stdout)
conn.send(stderr) except Exception: #针对windwos
break
conn.close() phone.close()
客户端:
import socket
import struct
import json
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) while True:
cmd=input('>>: ').strip()
if not cmd:continue
#发命令
phone.send(cmd.encode('utf-8')) #先收报头的长度
struct_res=phone.recv(4)
header_size=struct.unpack('i',struct_res)[0] #再收报头
header_bytes=phone.recv(header_size)
head_json=header_bytes.decode('utf-8')
head_dic=json.loads(head_json) total_size=head_dic['total_size']
#再收命令的执行结果
recv_size=0
data=b''
while recv_size < total_size:
recv_data=phone.recv(1024)
recv_size+=len(recv_data)
data+=recv_data #打印结果
print(data.decode('gbk')) phone.close()
实现并发的代码:
服务端:
import socketserver
class MyTcphandler(socketserver.BaseRequestHandler):
def handle(self):
while True: #通信循环
data=self.request.recv(1024)
self.request.send(data.upper())
if __name__ == '__main__':
#取代链接循环
server=socketserver.ThreadingTCPServer(('127.0.0.1',8080),MyTcphandler)
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()