2012-12-20 14 views
7

Przeszukuję z python i sieci.Python - konwertowanie sock.recv na ciąg

while True: 
    data = sock.recv(10240) 

To zdecydowanie słucham. Ale wydaje się, że trzeba go przekonwertować na ciąg tekstowy.

Widziałem ludzi korzystających z struct.unpack(), ale nie jestem pewien, jak to działa. W jaki sposób dokonać konwersji?

+1

Jaką wersję Pythona używasz? Odpowiedź będzie inna dla 2.x versus 3.x. –

+0

Wersja 3.3.0 Jak rozumiem, 2.x jest inny niż 3.x w niektórych funkcjach sieciowych – coffeemonitor

+0

@ coffeemonitor: To nie wszystko, co różni się w funkcjach sieciowych - ale jest całkiem inny w funkcjach obsługi tekstu, który jest dlaczego Joshua D. Boyd zadał to pytanie. – abarnert

Odpowiedz

15

Co wrócisz z recv jest bytes ciąg:

Odbieranie danych z gniazda. Wartością zwracaną jest obiekt bajtowy reprezentujący odebrane dane.

w Pythonie 3.x przekonwertować bytes ciąg na ciąg Unicode tekst str, trzeba wiedzieć, co zestaw znaków łańcuch jest zakodowany, więc można zadzwonić decode. Na przykład, jeśli jest to UTF-8:

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

(w Pythonie 2.x, bytes to samo, co str, więc już dostał ciąg mam Ale jeśli chcesz uzyskać Unicode. tekst unicode łańcuch, to jest taki sam jak w 3.x.)

powodem ludzie często używają struct jest to, że dane te nie są tylko 8-bitowy lub tekst Unicode, ale jakiś inny format. Na przykład możesz wysłać każdą wiadomość jako "netstring": długość (jako ciąg cyfr ASCII), a następnie separator :, następnie length bajtów UTF-8, następnie , - taki jak b"3:Abc,". (Istnieją warianty w tym formacie, ale jest to standardowa sieć Bernsteina.)

Powodem, dla którego ludzie używają Netstrings lub innych podobnych technik, jest to, że potrzebujesz sposobu na rozgraniczenie wiadomości podczas korzystania z TCP. Każdy recv może dać ci połowę tego, co przekazała druga strona z send, lub może dać twoje 3 send s i część czwartej. Tak więc, musisz zebrać bufor danych recv, a następnie wyciągnąć z niego wiadomości. I potrzebujesz sposobu, aby powiedzieć, kiedy jedna wiadomość się kończy, a druga zaczyna. Jeśli wysyłasz zwykłe wiadomości tekstowe bez żadnych znaków nowej linii, możesz po prostu użyć znaków nowej linii jako ogranicznika. W przeciwnym razie będziesz musiał wymyślić coś innego - może netstring lub użycie \0 jako ogranicznika lub użycie linii nowej linii jako ogranicznika, ale unikanie rzeczywistych linii nowego ciągu danych lub użycie samozasilonego sformatowanego formatu, takiego jak JSON.

+0

I to działa! Recv po prostu potrzebował tej konwersji. Zakładam, że jeśli mam wysłać dane z powrotem do źródła, będę musiał je zakodować? – coffeemonitor

+0

@ coffeemonitor: Dokładnie, jeśli masz ciąg, zakoduj go i "wyślij" wyniki. – abarnert

+0

@abarnert, czy możesz podzielić się dokładnie tym, jak ustalić, czy wiadomość kończy się na połowie punktu kodowego (druga połowa jest w następnej wiadomości). Na przykład, jeśli czytasz z gniazda i wiesz, że będzie to utf-8, skąd możesz wiedzieć, kiedy użyć .decode() na bajtach, gdy nie wiesz, czy ostatni bajt jest prawidłowym utf- 8 punktów kodowych .. – dylnmc

3

W języku Python 2.7.x i wcześniejszym, data jest już ciągiem. W języku Python 3.x, data jest obiektem bajtów. Aby przekonwertować bajty na łańcuch, użyj metody decode(). decode() będzie wymagać argumentu kodera-dekodera, takiego jak "utf-8".

Powiązane problemy