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脚本。这可能吗?我做错了什么?
很难从客户端代码中看出您使用了哪种客户端库来建立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)