c#向python发送整数

本文关键字:整数 python | 更新日期: 2023-09-27 18:01:39

我试图发送两个整数到python客户端脚本(这是在Linux机器上运行)从c#程序(服务器),这是在pc上运行,使用套接字技术。直到现在我还能发送字符串。

服务器:

TcpListener listener = new TcpListener(IPAddress.Any, 12345);
Invoke(new PrintMsg(printMsg), new object[] { "Trying to connect" });
listener.Start();
for(; ; ;)
{
   TcpClient client = null;
   try
   {
      client = listener.AcceptTcpClient();
      netStream = client.GetStream();
      Invoke(new PrintMsg(printMsg), new object[] { "Found client" });

      //send command to client
      ASCIIEncoding encoder = new ASCIIEncoding();
      byte[] buffer = encoder.GetBytes("Hello client");
      netStream.Write(buffer, 0, buffer.Length);
      netStream.Flush();
   }
   catch (Exception ex)
   {
      Invoke(new PrintMsg(printMsg), new object[] { ex.ToString() });
   }
}

客户端代码为:

while True:
    msg = s.recv(1024)
    print 'SERVER:', msg

所以我想把一个整数"放入"一个缓冲区数组,然后把它发送给python脚本。这可能吗?我做错了什么?

c#向python发送整数

很难从客户端代码中看出您使用了哪种客户端库来建立TCP连接。

为什么不使用一些支持c#和Python的消息队列实现,比如ZeroMQ?如果你需要更复杂的数据结构传递,你也可以考虑使用一些内存中的键值存储解决方案来实现队列,比如Redis。优点是消息队列服务器/客户端实现设计得很好,您只需要编写一两行代码来在业务逻辑中发送/接收。

在解决"如何发送整数"这个问题之前,您需要解决一个更大的问题:"如何发送消息?"

在TCP中,当你在一端调用send时,即使它一次发送整个缓冲区(这不能保证),另一端也可能在多个单独的recv调用中获得数据,而不是一次全部调用。更糟糕的是,它可能在单个recv中得到一个send的一部分和下一个send的一部分。

您可以使用更高级的协议(如ZeroMQ,甚至http)来为您处理这个问题。但是如果你只想使用原始TCP,你必须自己处理它。

一个明显的解决方案是使用像换行符(或NUL字节等)这样的分隔符,但是当然您需要在消息中间转义换行符。另一种可能是使用某种头来描述消息的其余部分,如netstring。或者您可以使用自定界消息类型,如JSON。

许多处理分隔符问题的非常简单的方法自动处理发送整数的问题。JSON包含数字作为一种类型。或者您可以将整数作为字符串通过netstring或换行符分隔的字符串发送。

如果你真的想用某种"二进制"方式对数字进行编码,你必须选择一种表示形式,并在每一边编写代码来转换和转换这种表示形式。例如,如果你想将内容限制为32位有符号整数,并以大端序C整数格式发送它们,则Python代码为buf = struct.pack('!I', number)number = struct.unpack('!I', buf)

但是您应该考虑是否需要二进制格式。作为一个人,它显然更难阅读和调试。它也更容易出错(例如,忘记了端序或单词大小)。简单的方法是有限的(例如,上面描述的!I格式对于大于20亿的数字将失败)。它甚至不一定更紧凑。通常,您要发送许多小数字,这些数字以2-3字节作为带换行符的字符串,但以二进制形式使用4字节。

下面是一个基于行的数字读取器的简单Python实现:

def read_numbers_off_socket(s):
    buf = ''
    while True:
        newbuf = s.recv(4096)
        if not newbuf:
            yield int(buf)
            break
        buf += newbuf
        lines = buf.split(''n')
        for line in lines[:-1]:
            yield int(line)

但是你可以更简单地使用s.makefile:

def read_numbers_off_socket(s):
    with s.makefile() as f:
        for line in f:
            yield int(line)