2013-03-16 2 views
0

Я некоторое время копался, и я ушел с хорошим пониманием, ничего, что доходит до того, что я пытаюсь сделать:Как узнать, какой клиент передает данные на мой сервер?

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

Как я могу определить, какой клиент запросил сервер, чтобы я мог ответить на него?

Я довольно новичок в Python, и сама функция select() немного запутанна. Я способен принимать новые подключения и получать входные данные, но сервер, похоже, не знает, к какому клиенту он относится (или, возможно, мой текст отладки неверен, и он знает?).

В любом случае, вот код для сервера:

while running: 
    #select returns 3 subsets of the input containing sockets that have stuff to be read, empty buffer for writing, or an error 
    readers, writers, error = select.select(input, output, errors) 
    for s in readers: 
     if s == serversocket: 
      #readable server socket is ready for connection 
      connection, client_addr = s.accept() 
      print >> sys.stderr, 'new connection from', client_addr 
      connection.setblocking(0) 
      #clients.append([client_addr, performance]) 
      input.append(connection) 
      output.append(connection) 
     else: 
      #readable socket, not ready for new connection 
      data = s.recv(1024) 
      print >> sys.stderr, "readable socket, not ready for new connection" 
      if data: 
       #the socket actually has data (put Compute process data into list) 
       print >> sys.stderr, "Data received" 
       substring = data[0:data.find("sss")]; 
       print >> sys.stderr, 'received %s from %s' % (substring, client_addr) 
       if substring == "-get": 
        print >> sys.stderr, 'received -get command' 
        determinerange() 
        print >> sys.stderr, 'sending range of %d to %d', currentlow, currenthigh 
        temp = currentlow+"\0" 
        connection.send(currentlow) 
        temp = currenthigh+"\0" 
        connection.send(currenthigh) 
       elif substring == "-k": 
        print >> sys.stderr, 'received -k, stopping' 

По существу, он получает какую-то команду, и оборачивается и посылает данные ему необходимо. В случае, если вам интересно, этот сервер должен поговорить с программой на C, которую я также пишу, что на самом деле делает расчеты. Вот почему я добавляю символ новой строки «\ 0». Если он получает -k от любого из клиентов, он должен остановить каждого клиента и выйти.

Примечание: Я могу использовать только стандартную библиотеку python. Я не могу получить какие-либо дополнительные вещи, которые упростили бы работу :)

Спасибо вам за вашу помощь заранее!

+0

Обычно что-то вроде этого находится в более крупной структуре. Установление соединения сокета будет одним шагом, затем оно будет перенаправлено на другой исполняемый процесс или модуль, который будет обрабатывать аутентификацию на основе некоторого предопределенного протокола. Сетевые объекты python здесь управляют некоторыми данными TCP от вас. Например, client_addr, который возвращается из accept(), даст вам IP-адреса отправителя. –

+0

Да. И я могу использовать это, чтобы возвращать данные этому клиенту, но только если никаких других подключений не произойдет до того, как я отправлю данные этому клиенту. Если приходит новое соединение, он устанавливает client_addr как самый новый подключенный клиент. Мне интересно, как вы отправляете данные обратно клиенту, который отправил вам данные, не зная client_addr для этого человека. EJP сказал, что вы просто отправляете его обратно в тот же сокет, так значит ли это, что выбор также содержит информацию о клиенте, когда я получаю данные? Когда я отправляю данные, он автоматически выбирает тот, который я только что получил? – FeralShadow

+0

Ссылка на объект сокета - это соединение с уникальным удаленным сервером. Вы можете в принципе отправлять или получать любые байты, которые вы хотите, предполагая, что оба конца согласны с тем, что с ним делать. [http://www.tutorialspoint.com/python/python_networking.htm](http://www.tutorialspoint.com/python/python_networking.htm) –

ответ

1

Попробуйте заменить строки:

   connection.send(currentlow) 
       ... 
       connection.send(currenthigh) 

по:

   s.send(currentlow) 
       ... 
       s.send(currenthigh) 

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

+0

Ого! Я вижу! Очень круто. Выбор по какой-то причине очень запутан для меня. – FeralShadow

+0

Хорошо, теперь я получаю таинственную сломанную трубу. Я предполагаю, что это должно быть в программе C. – FeralShadow

+0

На самом деле, я заметил, что теперь, после отправки данных с сервера, моя программа C получает его просто отлично, но тогда скрипт хочет закрыть соединение вместо того, чтобы слушать больше запросов. Почему это? – FeralShadow

1

Вам не нужно знать, какой клиент. Сокет - это клиент, во всех смыслах и целях. Просто отправьте ответ через тот же сокет, с которого вы получили запрос.

+0

Что мешает серверу отправлять сообщение всем подключенным клиентам? – FeralShadow

+0

Я понятия не имею, о чем вы говорите. Вам нечего мешать * вы * от * писать код таким образом, * если вы так решите, но сервер ничего не отправит, если вы не напишете какой-нибудь код, а код, который я предлагаю вам, отправляет клиенту запрос пришли из. – EJP

+0

А я вижу. Ну, я, по-видимому, принципиально неправильно понял, как работает Select(). Я думал, что это создание списков подключенных клиентов, и мне нужно было как-то указать, к кому отправлять данные. – FeralShadow

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