C ++服务器无法通过socket从python客户端读取我的消息

时间:2015-03-29 18:19:07

标签: python c++ sockets boost tcp

我编写了一个python客户端脚本,通过tcp将消息发送到服务器。

import socket

TCP_IP = '127.0.0.1'
TCP_PORT = 12003
BUFFER_SIZE = 1024
MESSAGE = b"Hello, World!"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()

print "received data:", data

服务器可以接收我的数据,但似乎无法读取数据。日志信息将在以下内容中复制。

I0328 21:45:24.493249   505 prset04.cpp:210] reading the message (3472609771221168177 bytes)
E0328 21:45:25.493088   505 prset04.cpp:162] unable to receive on socket
I0328 21:45:25.493285   505 prset04.cpp:215] echoing the message
E0328 21:45:25.493479   505 prset04.cpp:185] unable to send on socket

我认为C ++套接字模块和python之间可能存在一些不同之处。但我不知道那里出了什么问题,因为我不熟悉C ++和socket。

任何想法或解释都会非常有用!

由于

服务器代码:

static void OnClient(const int sk) {
    size_t len;
    char buf[1024];

    // Read the message length.
    if (!ReadBytes(sk, reinterpret_cast<char*>(&len), sizeof(len))) {
        LOG(ERROR) << "unable to read message length";
        return;
    }

    LOG(INFO) << "reading the message (" << len << " bytes" << ")";

    // Read the message.
    ReadBytes(sk, buf, len);

    LOG(INFO) << "echoing the message";

    // Echo the message.
    WriteBytes(sk, buf, len);
}

static bool ReadBytes(const int sk, char* buf, const size_t n) {
    char* ptr = buf;
    while (ptr < buf + n) {
        if (!SetReadTimeout(sk)) {
            return false;
        }

        auto ret = recv(sk, ptr, ptr - buf + n, 0);
        if (ret <= 0) {
            LOG(ERROR) << "unable to receive on socket";
            return false;
        }

        ptr += ret;
    }

    return true;
}

2 个答案:

答案 0 :(得分:0)

Galik指出你的python脚本不会发送任何长度的消息。虽然你的c ++服务器读取4个字节(如果你在64位linux上,则为8个字节),并期望它们是消息的长度。 所以前4个字节是&#34; Hell&#34;哪种二进制形式将是服务器尝试读取的相当大的字节数。

要解决此问题 - 在python脚本中将前4个字节作为消息长度发送。 此外,您还需要使用网络字节顺序(如果您打算使用二进制文件)以确保正确读取字节。 使用ntohl()函数将网络转换为主机字节顺序号。

答案 1 :(得分:0)

就像Galik已经说过的那样,Python不会在字符串之前发送字符串的长度,就像你的程序所期望的那样。而且C / C ++也没有这样做。

如果您希望Python程序与C程序一起使用,您需要考虑以下几点:

  1. 使用struct模块将字符串包含在
  2. 之前所需的长度
  3. 打包字符串时使用网络字节顺序
  4. 您应该知道size_t之类的声明是依赖于体系结构的,并且在64位和32位体系结构之间有所不同。如果希望它们在体系结构之间兼容,则可以使用固定大小的整数,如uint32_t
  5. 示例代码:

    from struct import pack
    message = "Hello World"
    data = pack('!i%ds' % len(message), len(message), message))
    

    如果您无法更改C代码以使用网络字节顺序,则您的特定代码应如下所示:

    from struct import pack
    message = "Hello World"
    data = pack('<Q%ds' % len(message), len(message), message))
    

    < =使用小端字节顺序

    Q =使用无符号64位整数(64位架构上的sizet_t