2015-03-06 3 views
1

В моем клиентском коде есть ошибка. Ошибка: «Операция была предпринята для чего-то, что не является сокетом». как я могу исправить эту ошибку. Я также знаю, что мой вход еще не отправлен на сервер, если у вас есть какие-то подсказки о том, как я выполню, что я тоже буду их любить. Благодаря! Код показал ниже: КодTCP-сервер чата Python 3.4

import socket, select, string, sys 


def prompt() : 
    sys.stdout.write('<You> ') 
    sys.stdout.flush() 

#main function 
if __name__ == "__main__": 

    host = "localhost" 
    port = 5000 

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    s.settimeout(2) 

    # connect to remote host 
    try : 
     s.connect((host, port)) 
    except : 
     print('Unable to connect') 
     sys.exit() 

    print('Connected to remote host. Start sending messages') 
    prompt() 
    input = input() 

    while 1: 
     socket_list = [sys.stdin, s] 

     # Get the list sockets which are readable 
     read_sockets, write_sockets, error_sockets = select.select(socket_list , [], []) 

     for sock in read_sockets: 
      #incoming message from remote server 
      if sock == s: 
       data = sock.recv(4096) 
       if not data : 
        print('\nDisconnected from chat server') 
        sys.exit() 
       else : 
        #print data 
        sys.stdout.write(data) 
        prompt() 

      #user entered a message 
      else : 
       msg = sys.stdin.readline() 
       s.send(msg) 
       prompt() 

Сервер:

import socket, select 

#Function to broadcast chat messages to all connected clients 
def broadcast_data (sock, message): 
    #Do not send the message to master socket and the client who has send us the message 
    for socket in CONNECTION_LIST: 
     if socket != server_socket and socket != sock : 
      try : 
       socket.send(message) 
      except : 
       # broken socket connection may be, chat client pressed ctrl+c for example 
       socket.close() 
       CONNECTION_LIST.remove(socket) 

if __name__ == "__main__": 

    # List to keep track of socket descriptors 
    CONNECTION_LIST = [] 
    RECV_BUFFER = 4096 # Advisable to keep it as an exponent of 2 
    PORT = 5000 

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    # this has no effect, why ? 
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    server_socket.bind(("0.0.0.0", PORT)) 
    server_socket.listen(10) 

    # Add server socket to the list of readable connections 
    CONNECTION_LIST.append(server_socket) 

    print("Chat server started on port " + str(PORT)) 

    while 1: 
     # Get the list sockets which are ready to be read through select 
     read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[]) 

     for sock in read_sockets: 
      #New connection 
      if sock == server_socket: 
       # Handle the case in which there is a new connection recieved through server_socket 
       sockfd, addr = server_socket.accept() 
       CONNECTION_LIST.append(sockfd) 
       print("Client (%s, %s) connected" % addr) 

       broadcast_data(sockfd, "[%s:%s] entered room\n" % addr) 

      #Some incoming message from a client 
      else: 
       # Data recieved from client, process it 
       try: 
        #In Windows, sometimes when a TCP program closes abruptly, 
        # a "Connection reset by peer" exception will be thrown 
        data = sock.recv(RECV_BUFFER) 
        if data: 
         broadcast_data(sock, "\r" + '<' + str(sock.getpeername()) + '> ' + data)     

       except: 
        broadcast_data(sock, "Client (%s, %s) is offline" % addr) 
        print("Client (%s, %s) is offline" % addr) 
        sock.close() 
        CONNECTION_LIST.remove(sock) 
        continue 

    server_socket.close() 
+1

как легкое в сторону - вы должны поставить меньше кода в 'если __name__ ==«__main__ "' и многое другое в функциях –

+0

Какая операционная система? 'sys.stdin' не будет работать как сокет в Windows. – tdelaney

+0

Это работало для меня на окнах? –

ответ

0

В Microsoft Windows библиотека сокетов python реализована с использованием Winsock. Winsock не интегрирован в операционную систему, такую ​​как библиотека сокетов в системах unixy. Он имеет свое представление о том, что такое сокет, и не распознает системные трубки или консоли.

В Windows вы получите ошибку вы видите

>>> import platform 
>>> print platform.system() 
Windows 
>>> import socket 
>>> import select 
>>> import sys 
>>> select.select([sys.stdin],[],[]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
select.error: (10038, 'An operation was attempted on something that is not a socket') 
>>> select.select([sys.stdin.fileno()],[],[]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
select.error: (10038, 'An operation was attempted on something that is not a socket') 
>>> 

В Linux это работает

>>> import platform                               
>>> print platform.system() 
Linux                                  
>>> import socket 
>>> import select 
>>> import sys 
>>> select.select([sys.stdin],[],[],0) 
([], [], []) 
>>> 
+0

Как я могу это исправить? –

+0

Кросс-платформенное решение заключается в использовании блокировки ввода-вывода с потоками и очереди, чтобы собрать все это вместе. – tdelaney

0

Я не мог видеть ничего плохого, так что я побежал ваш код на моем Linux коробку с python3.4 и получил никаких ошибок с любого сервера или клиент и они подключены без проблем. Единственное, о чем я могу думать, это ваша версия python или ОС, например, предлагаемая tdelaney. У меня нет окна для проверки, поэтому я не могу подтвердить, зависит ли это от ОС.

0
Use input = [s] #instead of socket_list = [sys.stdin, s]