TCP客户端无法写入套接字但接收工作正常

时间:2017-01-18 19:04:51

标签: python sockets

我有用python编写的客户端程序与某个服务器通信。

[客户]

import asyncore
import logging
import socket
import sys, threading, traceback
from cStringIO import StringIO

class Client(threading.Thread, asyncore.dispatcher):

    def __init__(self, host, port):
        self.logger = logging.getLogger()

        threading.Thread.__init__(self)
        self._thread_sockets = dict()
        asyncore.dispatcher.__init__(self, map=self._thread_sockets)

        # data members for the module
        self.host = host
        self.port = port
        self.write_buffer = ""
        self.is_connected = False
        self.read_buffer = StringIO()

        # Ok now to run the thread !!
        self.start()

    def run(self) :
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        address = (self.host, self.port)
        self.logger.debug('connecting to %s', address)

        # wait until server is up
        while not self.is_connected :
           try :
              self.connect(address)
           except Exception as ex :
              pass #do nothing, proceed forward !!
        asyncore.loop(map=self._thread_sockets)

    def handle_connect(self):
        self.is_connected = True
        self.logger.debug('handle_connect()')

    def handle_close(self):
        self.logger.debug('handle_close()')
        self.close()

    def handle_error(self):
        traceback.print_exc(sys.stderr)
        self.close()

    def writable(self):
        self.logger.debug('writable() : len is %d bytes', len(self.write_buffer))
        is_writable = (len(self.write_buffer) > 0)
        if is_writable:
            self.logger.debug('writable() -> %s', is_writable)
        return is_writable

    def readable(self):
        self.logger.debug('readable() -> True')
        return True

    def handle_write(self):
        sent = self.send(self.write_buffer)
        self.logger.debug('data len written to socket -> %s', sent)
        self.logger.debug('handle_write() -> "%s"', self.write_buffer[:sent])
        #self.write_buffer = self.write_buffer[sent:]

    def handle_read(self):
        data = self.recv(8192)
        self.logger.debug('handle_read() -> %d bytes', len(data))
        self.read_buffer.write(data)
        self.logger.debug('data received from socket -> %s', self.read_buffer.getvalue())
        self.read_buffer.truncate(0)

    def send(self, data) :
        self.write_buffer = data

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG,
                        format='%(name)s: %(message)s',
                        )
    try :
       client = Client("127.0.0.1", 8182)
       client.send('sending data from client')
    except Exception as ex :
       logging.exception(ex)
       sys.exit(1)

我能够正确地从服务器接收数据,但是发送到服务器的呼叫总是失败。从日志开始,发送总是返回'无'。

我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

您使用不发送任何数据但未返回任何值的代码覆盖send asyncore.dispatcher方法:

def send(self, data) :
    self.write_buffer = data

至少,您需要将代码更改为与此类似:

def send_data(self, data):
    self.write_buffer = data

和此:

client.send_data('sending data from client')

asyncore.dispatcher类已经有send方法,它是socket.send方法的包装器。来自asyncore.py

def send(self, data):
    try:
        result = self.socket.send(data)
        return result
    except socket.error, why:
        if why.args[0] == EWOULDBLOCK:
            return 0
        elif why.args[0] in _DISCONNECTED:
            self.handle_close()
            return 0
        else:
            raise

由于您覆盖了此方法,因此您的send方法会调用handle_write方法,并且不会向服务器发送任何数据。