一.socket(套接字)
1.基于TCP协议的socket通信
sever端
1 import socket
2 sk = socket.socket()
3 sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
4 sk.listen() #监听链接
5 conn,addr = sk.accept() #接受客户端链接
6 ret = conn.recv(1024) #接收客户端信息
7 print(ret) #打印客户端信息
8 conn.send(b'hi') #向客户端发送信息
9 conn.close() #关闭客户端套接字
10 sk.close() #关闭服务器套接字(可选)
client端
import socket
sk = socket.socket() # 创建客户套接字
sk.connect(('127.0.0.1',8898)) # 尝试连接服务器
sk.send(b'hello!')
ret = sk.recv(1024) # 对话(发送/接收)
print(ret)
sk.close() # 关闭客户套接字
2.标准通信循环
server端
import socket
server = socket.socket() # 生成一个对象
server.bind(('127.0.0.1',8080)) # 绑定ip和port
server.listen() # 半连接池
while True:
conn, addr = server.accept()
print(addr) # ('127.0.0.1', 51323) 客户端的地址
while True:
try:
data = conn.recv(1024)
print(data)
if len(data) == 0:break
conn.send(data.upper())
except ConnectionResetError as e:
print(e)
break
conn.close()
client端
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
while True:
msg = input('>>>:').encode('utf-8')
if len(msg) == 0:continue
client.send(msg)
data = client.recv(1024)
print(data)
3.粘包问题
server端
import socket
import subprocess
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
while True:
conn,addr = sk.accept()
while True:
try:
cmd = conn.recv(1024).decode('utf-8')
if len(cmd) == 0:break
res = subprocess.Popen(cmd,shell= True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read()
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError:
break
client端
import socket
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
cmd = input('请输入cmd:').strip()
if len(cmd) == 0 :continue
sk.send(cmd.encode('utf-8'))
res = sk.recv(1024)
print(res.decode('gbk'))
粘包造成的原因:
粘包现象只发生在tcp协议中:
1.从表面看,粘包问题主要是因为发送方和接收方的缓存机制,tcp协议面向流通信的特点
2.实际上,主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的
4.解决粘包
server端
import socket
import subprocess
import json
import struct
sk = socket.socket()
sk.bind(('127.0.0.1',8080))
sk.listen()
while True:
conn,addr = sk.accept()
while True:
try:
cmd = conn.recv(1024).decode('utf-8')
if len(cmd) == 0:break
res = subprocess.Popen(cmd,shell= True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read()
ret = stdout+stderr
head = {'name':'zzp','size':len(ret)}
json_head = json.dumps(head)
head_pack = struct.pack('i',len(json_head))
sk.send(head_pack)
sk.send(json_head.encode('utf-8'))
sk.send(ret)
except ConnectionResetError:
break
client端
import socket
import struct
import json
sk = socket.socket()
sk.connect(('127.0.0.1',8080))
while True:
cmd = input('请输入cmd:').strip()
if len(cmd) == 0 :continue
sk.send(cmd.encode('utf-8'))
head_pack = sk.recv(4)
head_len = struct.unpack('i',head_pack)[0]
head_json = sk.recv(head_len).decode('utf-8')
head = json.loads(head_json)
size = head['size']
recv_size = 0
real_data = b''
while recv_size < size:
data = sk.recv(1024)
real_data += data
recv_size += len(data)
print(real_data.decode('gbk'))