【问题标题】:sending the length of the buffer and receive it with C from python发送缓冲区的长度并用 C 从 python 接收它
【发布时间】:2015-08-24 09:49:11
【问题描述】:

我正在使用这个简单的 python 服务器代码来发送缓冲区的长度 我即将发送:

def server_mode(ip, port):    
    try:    
        s = socket()    
        s.bind((ip, port))    
        print ("[*] Listening on %s:%d\n[*] Waiting for clients" % (ip, port))    
        if ("win32" == os.sys.platform):    
            print("[*] Press Ctrl + Break to stop server")
            elif ("linux" in os.sys.platform):
                print("[*] Press Ctrl + C to stop server")
            while True:
                s.listen(MAX_CLIENTS)
                client, client_ip = s.accept()
                client_ip = client_ip[0]
                print("[*] Got connection from %s" % client_ip)
                buf = struct.pack(">I", 7313)
                client.send(buf)
                client.close()
        except KeyboardInterrupt:
            s.close()
            print("[*] Closed socket")
            exit()
        except:
            s.close()
            raise

然后使用这个 C 代码,客户端应该收到缓冲区的长度 我即将发送和分配缓冲区所需的位置并接收它:

    char* buf = malloc(4 * sizeof(char));
    recv(sockfd, buf, 4, 0);
    int buf_len = *buf;

它可以工作,但只转换 4 个字节 long int 的前两个字节, 例如,如果我用它发送大小为 13 的缓冲区的len,它可以正常接收,但在像 7313 这样的数字上,它会收到 54。

【问题讨论】:

  • 用python写丑陋的代码非常难,你刚刚做到了,恭喜。
  • @iharob :我认为 Stackoverflow 需要一些检测常见问题的助手作为源代码“按钮”。也许是回形针头像?
  • @MarcusMüllerꕺꕺ 任何能防止伤害我们眼睛的东西。您可以在堆栈溢出元数据上提出建议。
  • @iharob:我不会在 meta 上认真建议 Clippy -- 你知道,这是我的真名,我想在网上感到安全。
  • 为什么不将大小作为 ASCII 文本字符串发送?这会简单得多。

标签: python c struct


【解决方案1】:

这个:

int buf_len = *buf;

不会神奇地从buf 读取sizeof buf_len(您似乎认为它是四个)字节,因为*bufchar 类型的值。

您应该使用uint8_t 而不是char,以及uint32_t 而不是int,并且根据需要阅读尽可能多的内容,当然要尊重字节序:

uint8_t buf[4];
if(recv(sockfd, buf, sizeof buf, 0) == 4)
{
  const uint32_t buf_len = ((uint32_t) buf[0] << 24) |
                           ((uint32_t) buf[1] << 16) |
                           ((uint32_t) buf[2] << 8) |
                           buf[3];
  ...
}

【讨论】:

  • 我希望它是四个,因为我在 python 服务器代码中使用了 struct.pack,它将值打包为 int 的四个字节
  • @user3609537 我知道您希望网络上有四个字节,但这不会使 int 在 C 中产生四个字节,而这似乎是您期望以某种方式发生的。
  • 所以如果我用 uint32_t 替换 int 它应该解决这个问题吗?因为它不是
  • @cdarke 另一端是 Python。他在 Python 代码中明确使用大端封装,这就是我使用大端的原因。
  • @user3609537 您没有阅读我上面的全部答案吗?我确实发布了更多的代码,而不仅仅是从 intuint32_t 的一次更改。你知道,那个代码不是为了好玩。 :)
猜你喜欢
  • 2010-11-09
  • 2013-02-16
  • 2018-11-08
  • 1970-01-01
  • 2018-07-13
  • 2022-10-01
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
相关资源
最近更新 更多