2012-12-20 45 views
7

我正在挖掘python和网络。Python - 将sock.recv转换为字符串

while True: 
    data = sock.recv(10240) 

这绝对是倾听。但它似乎需要转换为文本字符串。

我见过一些人使用struct.unpack(),但我不确定它是如何工作的。 什么是转换的方式?

+1

你使用的是什么版本的Python?答案与2.x和3.x不同。 –

+0

版本3.3.0 据我了解,在某些网络功能中,2.x与3.x不同。 – coffeemonitor

+0

@coffeemonitor:网络功能并不完全不同 - 但它在文本处理功能方面有很大不同,为什么约书亚博伊德问这个问题。 – abarnert

回答

15

recv得到什么是bytes字符串:

从套接字接收数据。返回值是一个表示接收到的数据的字节对象。

在Python 3.x中,为bytes字符串转换成Unicode文本字符串str,你要知道什么字符集编码与字符串,这样你就可以调用decode。例如,如果是UTF-8:

stringdata = data.decode('utf-8') 

(在Python 2.x中,bytes是一回事str,所以你已经得到了一个字符串,但是,如果你想获得一个Unicode。文本unicode字符串,它与3.x中的相同)

人们经常使用struct的原因是数据不仅仅是8位或Unicode文本,而是其他一些格式。例如,您可能会将每条消息发送为“netstring”:长度(作为ASCII数字串),后跟:分隔符,然后是length字节的UTF-8,然后是,-如b"3:Abc,"。 (格式上有变体,但是这是伯恩斯坦标准网络字符串。)

人们使用网络或其他类似技术的原因在于,当您使用TCP时,您需要某种方式来分隔消息。每个recv可以给你一半的对方通过send,或它可以给你的3 send和第四部分。因此,您必须累积一个recv数据的缓冲区,然后将消息从其中取出。你需要一些方法来告诉一个消息何时结束,以及下一个消息何时开始。如果您只是发送不带任何换行符的纯文本消息,则可以使用换行符作为分隔符。否则,你必须想出其他的东西 - 可能是netstrings,或者使用\0作为分隔符,或者使用换行符作为分隔符,但转义数据中的实际换行符,或者使用一些自定义的结构化格式(如JSON)。

+0

它的工作原理! recv只是需要转换。 我假设我要将数据发回它的源代码,我必须对它进行编码? – coffeemonitor

+0

@coffeemonitor:的确,如果你有一个字符串,对它进行编码并发送结果。 – abarnert

+0

@abarnert你能介意如何确定一个消息是否以一个码点的一半结束(另一半在下一个消息中)。例如,如果您正在从一个套接字读取数据,并且您知道它将是utf-8,那么如何知道何时在字节上使用.decode()时,如果不知道最后一个字节是否是有效的utf- 8码点.. – dylnmc

3

在Python 2.7.x和之前,data已经是一个字符串。在Python 3.x中,data是一个字节对象。要将字节转换为字符串,请使用decode()方法。 decode()将需要编解码器参数,如'utf-8'。