Python: Socket: обработка TCP-соединений по сотовой сети - PullRequest
3 голосов
/ 21 июня 2011

Я занимаюсь программированием сокетов на python, в котором я разрабатываю клиентский сокет TCP / IP для связи с медленным встроенным устройством. Поэтому иногда, когда предполагается, что ответом является только один пакет, он разбивается на два пакета. Мое текущее решение для этого - sleep() программа python, ожидающая, что все нужные мне данные уже получены.

comSocket.send('\r')

sleep(1)

comSocket.send('\r')

comSocket.recv(128)

comSocket.send('\r\r')

comSocket.recv(256)



#sending I commands for data

comSocket.send('1I\r\r3I\r\r4I\r\r13I\r\r5I\r\r8I\r\r7I\r\r9I\r\r')

sleep(2)

#receiving data

rawData = comSocket.recv(512)

sleep(1.5)

Мне интересно, есть ли лучший способ справиться с этой ситуацией?

Ответы [ 3 ]

1 голос
/ 21 июня 2011

Если это одно устройство, вы должны использовать решение, которое обрабатывает низкоуровневые socket взаимодействия для вас ... У python есть несколько таких как pexpect, exscript или paramiko (только ssh) ... если это несколько устройств и вам требуется асинхронная связь, используйте ответ @ zeekay (хотя асинхронное программирование, особенно с витой, неприятно, если вы не уже знаком с ним).

Я ответил на вопрос, как вы telnet и отправляете список команд на одно устройство здесь ...

Поймать процесс умирания в перспективе

Ответ, приведенный выше, делает код эффективным, но для новичка сложнее понять ... Следующий код проще, он устанавливает соединение telnet на TCP / 23, ожидает *, отправляет команду и помещает ответ на команду в mydata1 ...

import pexpect as px
import sys

def send_this(child, retcode, COMMAND):
    if retcode == 2:
        child.sendline(COMMAND)
    else:
        raise RuntimeError, "Could not complete login, due to socket error"

def expect_this(child, EXPR, timeout = 10):
    return child.expect([px.TIMEOUT, px.EOF, EXPR], timeout = timeout)

HOST = '192.168.49.49'
CMD1 = '1I'
PROMPT = '\*'     #Note: you might not need the backslash
TIMEOUT = 10

child = px.spawn('telnet %s' % HOST)
retcode = expect_this(child, PROMPT)
send_this(child, retcode, CMD1)
retcode = expect_this(child, PROMPT)
mydata1 = child.before    # mydata has the output from CMD1

Независимо от решения, самое важное - настроить время ожидания, чтобы вам не пришлось беспокоиться о длительных задержках в сотовой сети (которые, по моему опыту, иногда превышают 5 секунд).

Другая неприятная динамика в сотовой связи - это то, что многие потребительские устройства регулярно меняют свой IP-адрес при перемещении (из-за их зависимости от dhcp) ... TCP мало что может сделать, если это происходит ... если у вас нет статического адреса, соединение будет разорвано, когда устройство получит новый IP-адрес.

1 голос
/ 21 июня 2011

Используйте сетевую библиотеку, такую ​​как витая или zeromq .

0 голосов
/ 21 июня 2011

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

condition = True
while condition:
    rawData += sock.recv(512)
    # parse rawData to check if message is complete and if so you can set condition = False to break the loop
    if parser.is_complete(rawData):
        condition = False
...