首页 > 代码库 > Python 学习笔记 - socket(2)

Python 学习笔记 - socket(2)

前面学习了基本的最原始的单线程的socket的原理,下面学习一个新的知识点-粘包。由于我们接受的命令是recv(1024),那么如果当另一端发送的数据大于1024个字节的时候,他就会出现粘包的问题。每次只能发送1024个字节,如果我们直接放在一个循环里面不断发送,不断接受,那么当数据发完以后,他就会卡住在那里,因为我们知道在正常连接状态里,socket的accept和recv都是会进入阻塞的状态(换句话说,没有客户连接或者客户发空包,那么就会卡住!)。如何处理这个问题呢?一个思路是发送之前,先打个招呼,告诉对方自己要发送的字节长度,这样对方可以根据长度判断什么时候终止接受。


下面看一个模拟SSH操作的实例,客户端发送命令,服务器端执行之后返回结果给客户端


Server.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket
import subprocess #导入执行命令模块
ip_port=(‘127.0.0.1‘,9999) #定义元祖
#买手机
s=socket.socket()  #绑定协议,生成套接字
s.bind(ip_port)    #绑定ip+协议+端口:用来唯一标识一个进程,ip_port必须是元组格式
s.listen(5)        #定义最大可以挂起胡链接数

while True:  #用来重复接收新的链接
    conn,addr=s.accept()   #接收客户端胡链接请求,返回conn(相当于一个特定胡链接),addr是客户端ip+port
    #收消息
    while True: #用来基于一个链接重复收发消息
            try: #捕捉客户端异常关闭(ctrl+c)
                recv_data=http://www.mamicode.com/conn.recv(1024) #收消息,阻塞>


client.py

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket
ip_port=(‘127.0.0.1‘,9999)
s=socket.socket()
s.connect(ip_port)  #链接服务端,如果服务已经存在一个好的连接,那么挂起
while True:        #基于connect建立的连接来循环发送消息
    send_data=http://www.mamicode.com/input(">>: ").strip()
    if send_data == ‘exit‘:break
    if len(send_data) == 0:continue
    s.send(bytes(send_data,encoding=‘utf8‘))
    #解决粘包问题
    ready_tag=s.recv(1024) #收取带数据长度的字节:Ready|9998
    ready_tag=str(ready_tag,encoding=‘utf8‘)
    if ready_tag.startswith(‘Ready‘):#Ready|9998
        msg_size=int(ready_tag.split(‘|‘)[-1])  #获取待接收数据长度
    start_tag=‘Start‘
    s.send(bytes(start_tag,encoding=‘utf8‘)) #发送确认信息
    #基于已经收到的待接收数据长度,循环接收数据
    recv_size=0
    recv_msg=b‘‘
    while recv_size < msg_size:
        recv_data=http://www.mamicode.com/s.recv(1024)>




本文出自 “麻婆豆腐” 博客,请务必保留此出处http://beanxyz.blog.51cto.com/5570417/1860016

Python 学习笔记 - socket(2)