2016-11-08 5 views
0

Я делаю клиент-серверную программу, и есть проблема с клиентской частью. Проблема заключается в бесконечном получении данных. Я тестировал этот класс, указанный ниже, в интерпретаторе python. Я succesfuly (возможно не) подключен к Google, но тогда программа купируются в функции recvData() в данных = self.socket.recv (1024)Не удается получить данные из сокета

class client(): 
def __init__(self, host, port): 
    self.host = host 
    self.port = port 

    self.socket = self.connect() 
    self.command = commands() 


def connect(self): 
    ''' 
    Connect to a remote host. 
    ''' 
    try: 
     import socket 
     return socket.create_connection((self.host, self.port)) 
    except socket.error: 
     print(":: Failed to connect to a remote port : ") 

def sendCommand(self, comm): 
    ''' 
    Send command to remote host 
    Returns server output 
    ''' 
    comman = comm.encode() 
    # for case in switch(comman): 
    #   if case(self.command.RETRV_FILES_LIST.encode()): 
    #    self.socket.send(b'1') 
    #    return self.recvData() 

    #   if case(): 
    #    print(":: Got wrong command") 

    if (comman == b'1'): 
     self.socket.send(b'1') 
     return self.recvData() 

def recvData(self): 
    ''' 
    Receives all the data 
    ''' 
    i = 0 
    total_data = [] 
    while(True): 
     data = self.socket.recv(1024) 
     if not data: break 
     total_data.append(data) 
     i += 1 
     if i > 9: 
      break 
    return total_data 

о комментировал часть: Я думал, проблема в реализации Case , поэтому используется только оператор if-then. Но это не так.

+0

Вы вызываете 'recvData 'и он вешает навсегда? – tdelaney

+0

Не могли бы вы добавить немного больше информации об исходе запуска кода (вы получаете исключение?), и что вы ожидаете от результата? – glibdud

+0

Да, это так, блоки при получении данных – Fireship

ответ

0

Ваша проблема заключается в том, что self.socket.recv(1024) возвращает только пустую строку, когда сокет был отключен на стороне сервера, и все данные были получены. Как вы закодировали своего клиента, он не знает, что получено полное сообщение и ждет большего. Как вы решаете проблему, очень многое зависит от протокола, используемого сервером.

Рассмотрите веб-сервер. Он отправляет заголовок с разделителями строк, включающий параметр content-length, указывающий клиенту точно, сколько байтов он должен прочитать. Клиент сканирует новые строки до тех пор, пока заголовок не будет завершен, а затем будет использовать это значение, чтобы сделать recv(exact_size) (если он большой, он может читать фрагменты вместо этого), так что recv не будет блокироваться при входе последнего байта.

Даже тогда, есть решения сделать. Клиент знает, насколько велика веб-страница, но может захотеть отправить частичные данные вызывающему абоненту, чтобы он мог начать рисовать страницу до того, как все данные будут получены. Конечно, вызывающий абонент должен знать, что происходит - есть протокол или набор правил для самого API.

Необходимо определить, как клиент знает, что сообщение завершено и что именно оно передает обратно вызывающему абоненту. Отличный способ, чтобы справиться с этой проблемой, чтобы позволить какой-либо другой протокол, такой как [ZeroMQ] (http://zeromq.org/ сделать работу для вас. Простой питон клиент/сервер может быть реализован с xmlrpc. И есть много других способов.

Вы сказали, что внедряете клиент/серверную программу, тогда вы упомянули «подключен к Google» и telnet ... Все это очень разные вещи, и одна из них не будет работать со всеми из них.

+0

благодарю вас за ответ! Проблема заключалась в отправке сообщения в google с окончанием строки '\ n' Но спасибо за zeromq, он идеально подходит для моего любимого проекта :) – Fireship

+0

@ Fireship Great! Простое чтение шаблонов zeromq - лучшее введение в сетевое программирование на планете. – tdelaney

Смежные вопросы