如何在 Python 客户端实现数据收发并行处理

客户端需要同时发送和接收数据,但当没有数据从服务器接收时,客户端会挂起,导致无法发送数据。
在这里插入图片描述

  1. 解决方案:
    使用多线程实现数据的收发并行处理。
from socket import *
from threading import *
import thread
import time
from struct import pack,unpack
from networklingo import *
#from exception import *

HOST = '192.168.0.105'
PORT = 21567
BUFFSIZE = 1024
ADDR = (HOST,PORT)

lock = thread.allocate_lock()

class TronClient:

    def __init__(self,control=None):
        self.tcpSock = socket(AF_INET,SOCK_STREAM)
        #self.tcpSock.settimeout(.2)
        self.recvBuff = []

    def connect(self):
        self.tcpSock.connect(ADDR)
        self.clientUID = self.tcpSock.recv(BUFFSIZE)
        print 'My clientUID is ', self.clientUID
        t = Thread(target = self.receiveFromSrv())
        t.setDaemon(1)
        t.start()
        print 'going to main loop'
        self.mainLoop()


    def receiveFromSrv(self):
        RECIEVING = 1
        while RECIEVING:
            # 非阻塞模式下,当没有数据时不会阻塞
            self.tcpSock.setblocking(0)
            try:
                data = self.tcpSock.recv(BUFFSIZE)
            # 当数据为空时,继续等待
            except socket.error as e:
                if e.errno == EINTR:
                    continue
                else:
                    print('Error recieving data, ',e)
                    continue
            # 收到数据后,进行处理
            if not data: continue

            header = data[:6]
            msgType,msgLength,clientID = unpack("hhh",header)
            print(msgType)
            print(msgLength)
            print(clientID,'\n')

            msg = data[6:]

            while len(msg) < msgLength:
                data = self.tcpSock.recv(BUFFSIZE)
                dataLen = len(data)

                if dataLen <= msgLength:
                    msg += data
                else:
                    remLen = msgLength-len(data) #we just need to retrieve first bit of data to complete msg
                    msg += data[:remLen]
                    self.recvBuff.append(data[remLen:])

            print(msg)

    def disconnect(self,data=''):
        self.send(DISCONNECT_REQUEST,data)
        #self.tcpSock.close()

    def send(self,msgType,msg):
        header = pack("hhh",msgType,len(msg),self.clientUID)
        msg = header+msg
        self.tcpSock.send(msg)

    def mainLoop(self):
        while 1:
            # 非阻塞模式下,当没有数据时不会阻塞
            self.tcpSock.setblocking(0)
            try:
                data = raw_input('> ')
            except EOFError:            # enter key hit without any data (blank line) so ignore and continue
                continue
            # 数据为空,继续循环
            if not data or data == '':
                continue
            # 输入为 exit 时,断开连接并退出
            if data=='exit':            
                self.disconnect()
                break
            # 否则,发送数据
            else:
                self.send(TRON_CHAT,data)

if __name__ == "__main__":
    cli = TronClient()
    cli.connect()

在这个代码中,客户端在 receiveFromSrv 函数中设置了非阻塞模式,这样当没有数据时不会阻塞,而是继续执行 mainLoop 函数中的代码,从而实现数据的收发并行处理。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值