LINUX.ORG.RU

[python][сокеты][ниасилил] Слепой клиент.

 , ,


0

1

Суть проблемы в следующем, сервер отправляет на клиент данные такого вида:

{«action»: «update», «mana»: [[13, 2, 2, 2, 2, 4], [4, 4, 4, 3, 8, 2]], «deck_cards»: [{«life_cards»: [«Apostate», «Paladin», «Unicorn», «Rejuvenation»], «death_cards»: [«Lich», «StealLife», «GrimReaper», «ChaosVortex»], «earth_cards»: [«Golem», «Revival», «Echidna», «Satyr»], «water_cards»: [«Poseidon», «IceWizard», «AcidStorm», «Nixie»], «air_cards»: [«Gargoyle», «Plague», «BlackWind», «Manticore»], «fire_cards»: [«FlamingArrow», «Armageddon», «Devil», «Salamander»]}, {«life_cards»: [«LifeSacrifice», «Bless», «MagicHealer», «Purify»], «death_cards»: [«Vampire», «Curse», «Darklord», «Zombie»], «earth_cards»: [«Restructure», «Quicksands», «Earthquake», «Centaur»], «water_cards»: [«Leviathan», «Waterfall», «Poison», «IceGuard»], «air_cards»: [«Zeus», «Titan», «Phoenix», «ChainLightning»], «fire_cards»: [«Efreet», «RedDrake», «Demon», «Firelord»]}], «answ»: 200}

А клиент принимает данные такие:

{«action»: «update», «mana»: [[13, 2, 2, 2, 2, 4], [4, 4, 4, 3, 8, 2]], «deck_cards»: [{«life_cards»: [«Apostate», «Paladin», «Unicorn», «Rejuvenation»], «death_cards»: [«Lich», «StealLife», «GrimReaper», «ChaosVortex»], «earth_cards»: [«Golem», «Revival», «Echidna», «Satyr»], «water_cards»: [«Poseidon», «IceWizard», «AcidStorm», «Nixie»], «air_cards»: [«Gargoyle», «Plague», «BlackWind», «Manticore»], «fire_cards»: [«FlamingArrow», «Armageddon», «Devil», «Salamander»]}, {«life_cards»: [«LifeSacrifice», «Bless», «MagicH

Отпраляет сервер данные через socket.send

Клиент принимает данные через socket.recv. И вот что меня тут смущает, без разницы что указано в recv хоть 1024, хоть 4096. Обрезается в одном и том же месте.

С сервера данные точно уходят корректными. Разбивать на пакеты не хочется.

http://pastebin.com/cWFQaiRG

Тут не весь код, а только то, что отвечает за прием/отправку ( 2 строки )

P.S. кстати я наверное погорячился когда сказал что данные с сервера уходят корректными

print query - корректен

socket.send(query) - насчет этого я не могу быть уверен

Chubakur ★★
() автор топика

Наск я помню, никто не обещал, что recv прочитает стока, скока указано - обещали что recv прочитает не больше чем указно. Надо смотреть сколько прочитано и читать до тех пор пока не возьмете скока нужно.

И хорошо вначале передавать длину сообщения, скажем строкой из восьми байт, что б угадайку не играть.

AIv ★★★★★
()
Ответ на: комментарий от AIv

Надо смотреть сколько прочитано и читать до тех пор пока не возьмете скока нужно.

Это насколько я понимаю надо разбить ответ на несколько сообщений?

Chubakur ★★
() автор топика
Ответ на: комментарий от Chubakur

разобьет он все сам, Ваша задача собрать.


def mysend( connect, S ) : 
    connect.send('%08i'%len(S))
    connect.send(S)

def myrecv( connect ) :
    l, S = int( connect.recv(8) ), ''
    while len(S)<l : S += connect.recv( l-len(S) )
    return S

как то так.

AIv ★★★★★
()
Ответ на: комментарий от Chubakur

Не нашел ничего нужного.

facepalm.jpg

    def mysend(self, msg):
        totalsent = 0
        while totalsent < MSGLEN:
            sent = self.sock.send(msg[totalsent:])
            if sent == 0:
                raise RuntimeError("socket connection broken")
            totalsent = totalsent + sent

    def myreceive(self):
        msg = ''
        while len(msg) < MSGLEN:
            chunk = self.sock.recv(MSGLEN-len(msg))
            if chunk == '':
                raise RuntimeError("socket connection broken")
            msg = msg + chunk
        return msg
geekless ★★
()
Ответ на: комментарий от geekless

«Assuming you don’t want to end the connection, the simplest solution is a fixed length message:...»

Я себе в жизни как то с большим трудом представляю fixed length message - хотя наверное бывают...

AIv ★★★★★
()
Ответ на: комментарий от Chubakur

Вкратце, суть в том, что send и recv не гарантирует что прочтёт всё сразу, и даже указанный размер. В качестве костыля есть sendall, который не показывает ошибку, а вот для recv такого нет, так что надо всё делать руками.

anonymous
()

Твоя попытка работать с сетью описана в Top 10 Lame TCP/IP errors. Где-то ближе к концу, то есть к самому леймовому.

Vamp
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.