2015-05-26 3 views
1

У меня был компьютер с Windows, подключенный к моему Linux-серверу python.Windows select() только принимает, не отправляет

Сервер работает очень хорошо для пользователей Linux, но я хочу, чтобы он работал и в Windows. Я сделал некоторые исследования и выяснили, что select.select() функция на Windows, работает без стандартного ввода конвейеру, но когда я делаю это, он не отправляет данные на сервер, только получает.

Код:

__author__ = 'root' 
import socket 
import datetime 
import getpass   # Get username 
import sys 
import threading 
import thread 
import select 

def client(): 

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    address = "192.168.1.17" 
    sock.bind((str("192.168.1.231"), int(2222))) 
    sock.connect(("192.168.1.17", int(23657))) 
    sock.setblocking(0) 
    sock.send(getpass.getuser()+"[$ID$]zivofek") 

    socket_list = [sys.stdin, sock] 
    partner = raw_input("Chat partner: ") 

    while 1: 
     try: 
      message = raw_input() 
      sock.sendall(message) 
      data = sock.recv(1024) 
      print data 
     except: 
      continue 

def get_time(): 
    return datetime.datetime.strftime(datetime.datetime.now(), '%H:%M:%S') 

def main(): 
    client() 

if __name__ == "__main__": 
    main() 

Любая идея, как сделать оба приема и отправки в то же время в Windows?

+0

'select' сам по себе ничего не посылает. Вы имеете в виду, что вы не получаете «записи»? Опять же, размещение кода, который показывает проблему, является лучшим вариантом. –

+0

Фактически - у меня нет клиентского кода в окнах. Я в основном хочу, чтобы клиент мог получать и отправлять на сервер .. каким-либо образом. В python он работал с простым выбором - когда он записывается, когда он читается, читается. Я ищу способ реализовать его в окнах, но мне удалось сделать только одно, а не то, и другое. –

+0

Выполнена функция python 'socket.sendall()'? –

ответ

0

Не устанавливайте розетку без блокировки, если вы действительно не хотите мультиплексировать события из разных источников (т. Е. Когда не используется select()).

Здесь просто нормальная блокировка sendall() сделаю. Также проверьте обратную длину recv() - она ​​возвращается, когда есть некоторые данные, и получение нулевых байтов означает, что другой конец закрыл соединение.

Опять же, не надо bind() или установить SO_REUSEADDR на клиентские сокеты TCP.

0
socket_list = [sys.stdin, sock] 

Предполагая, что цель выше socket_list является передать его в выберите() ... это не будет работать. Реализация Windows select() работает только с сокетами, а sys.stdin не является сокетом.

Нет проблем с этим решением (*); что один из способов обработки этой проблемы - считывание из sys.stdin в отдельном потоке и передача этого потока() данных на один конец пары подключенных сокетов и размещение другого конца пары в список, который вы проходите, чтобы выбрать(). Кроме того, вы можете поместить таймаут в select(), чтобы select() возвращал каждый так часто, чтобы ваш четный цикл check, чтобы увидеть, есть ли какие-либо байты, доступные на stdin (хотя этот механизм будет либо неэффективным CPU, либо иметь высокую задержку , в зависимости от значения тайм-аута, которое вы передаете для выбора() - независимо от того, приемлемо это или нет, будет зависеть от вашего конкретного сценария использования)

(*) Хорошо, есть одно легкое исправление: не беспокойтесь, пытаясь запустить программа в Windows ...;)

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