Python socket recv(客户端)

时间:2013-11-29 14:34:46

标签: php python sockets

我必须通过socket连接到api并发送/ recv一些数据。 该公司发给我一个带有此代码的php-example文件,用于从套接字读取数据:

function readAnswer() {
        $size = fgets($this->socketPtr, 64);    

        $answer = "";           
        $readed = 0;

        while($readed < $size) {
            $part = fread($this->socketPtr, $size - $readed);   
            $readed += strlen($part);
            $answer .= $part;
        }
        return $answer;
    }

这对我有用。但是在python中,我偶尔会遇到错误。 并非套接字中的所有东西都是recv。 我的python尝试看起来像这样:

def read_answer(self,the_socket,timeout=0.5):
        the_socket.setblocking(0)   
        total_data=[]
        data=''     
        begin=time.time()
        while 1:
            if total_data and time.time()-begin > timeout:
                break
            elif time.time()-begin > timeout*2:
                break
            try:
                data = the_socket.recv(8192)
                if data:
                    total_data.append(data)
                    begin=time.time()
                else:
                    time.sleep(0.1)
            except:
                pass
        return ''.join(total_data)

我将数据作为dict /数组来恢复。并且我不时得到一个int(我认为msg长度) 那么什么是从套接字读取数据的更好方法。 啊,api以正确的方式发送数据,我检查了这个。它只是这个小功能;(

使用下面的代码(感谢falsetru)并添加了一个readed = len(数据)后,我遇到了另一个问题: 这是工作的PHP代码:

 function _parse_answer($answerData)
        {
            $result = array();
            $lines = explode("\n", $answerData);
            $data = explode("&", $lines[0]);
            foreach($data as $piece)
            {
                $keyval = explode("=", $piece, 2);
                $result[$keyval[0]] = $keyval[1];
            }
            for($i=1;$i<count($lines);$i++)
            {
                $result["csv"][]=$lines[$i];
            }
            return $result;
        }

这是我糟糕的python代码:

def parse_answer(self,data):
        #print "dd_demo_api: answer: (%s)" % (data)
        if data:
            result = {}
            lines = data.split("\n")
            index_list = 0
            if len(lines) == 1:
                index_list = 0
            else:
                index_list = 1
            pieces = lines[index_list].split("&")
            for x in pieces:
                keyval = x.split("=")
                result[keyval[0]] = keyval[1]
            iterlines = iter(lines)
            next(iterlines)
            next(iterlines)
            count = 1
            result["csv"] = {}
            for x in iterlines:
                result["csv"][count] = x.split(";")
            return result
        else:
            return 0

我认为这需要一些优化? ;(

1 个答案:

答案 0 :(得分:1)

Python版本与PHP版本不同。

请尝试以下代码:

def read_answer(self, sock):
    size = int(sock.recv(64).strip().rstrip('\0'))

    # Above is not exactly same as `fgets`.
    # If that causes an issue, use following instead.
    #
    # f = sock.makefile('r')
    # size = int(f.readline(64).rstrip('\0'))
    #
    # and replace `sock.recv(n)` with `f.read(n)` in the following loop.

    total_data = []
    readed = 0
    while readed < size:
        data = sock.recv(size - readed)
        if data:
            total_data.append(data)
            readed += len(data)
    return b''.join(total_data)