2013-05-13 31 views
7

Tôi đang viết một chương trình trò chuyện dựa trên socket đơn giản cho phép máy chủ gửi và nhận tin nhắn cho khách hàng. Khách hàng có thể gửi tin nhắn đến máy chủ nhưng khi tôi thử gửi một tin nhắn từ máy chủ, nó đổ vỡ nói rằng 'tập tin' đối tượng có thuộc tính 'recv'.chương trình trò chuyện python đơn giản dựa trên ổ cắm

Server.py

import socket 
import os 
import select 
import sys 

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

try: 
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except: 
    print 'Failed to create socket' 
    sys.exit() 

PORT = 9050 
HOST = '127.0.0.1' 
RECV_BUFFER = 4096 

server_socket.bind((HOST, PORT)) 
server_socket.listen(10) 

input = [server_socket, sys.stdin] 

print 'Chat Program' 
prompt() 

while 1: 

    inputready, outputready, exceptready = select.select(input,[],[]) 

    for sock in inputready: 

     if sock == server_socket: 
      client, address = server_socket.accept() 
      input.append(client) 
      #data = sock.recv(RECV_BUFFER) 
      #if data: 
       #sys.stdout.write(data) 
     else: 
      data = sock.recv(RECV_BUFFER) 
      if data: 
       sys.stdout.write(data) 
      else: 
       msg = sys.stdin.readline() 
       server_socket.send('\r<Server>: ' + msg) 
       prompt() 



server_socket.close() 

Client.py

import socket 
import os 
import select 
import sys 

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

HOST = '127.0.0.1' 
PORT = 9050 
try: 
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
except socket.error: 
    print 'Failed to create socket' 
    sys.exit() 

s.connect((HOST, PORT)) 

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

while 1: 

    socket_list = [sys.stdin, s] 

    read_sockets, write_sockets, error_sockets = select.select(socket_list, [], []) 

    for sock in read_sockets: 
     if sock == s: 
      data = sock.recv(4096) 
      if not data: 
       print '\nDisconnected from chat server' 
       sys.exit() 
      else: 
       sys.stdout.write(data) 
       prompt() 
     else: 
      msg = sys.stdin.readline() 
      s.send('\r<Client>: ' + msg) 
      prompt() 
+0

Đây không phải là ngang ngang nhau bởi vì nó có một máy chủ – ioanD

Trả lời

4

Vâng, trong máy chủ của bạn, bạn đang làm (viết tắt)

input = [server_socket, sys.stdin] 
inputready, outputready, exceptready = select.select(input,[],[]) 
for sock in inputready: 
    if sock == server_socket: 
     ... 
    else: 
     data = sock.recv(RECV_BUFFER) 

Vì vậy, khi một cái gì đó do thỏa thuận hợp trên sys.stdin, của nó không phải server_socket vì vậy nó đi đến else và cố gắng để recv, nhưng nó không phải là một ổ cắm. stdin nên sử dụng read không phải recv. Cấu trúc như hình dưới đây có ý nghĩa nhất đối với tôi.

if sock == server_socket: 
    ... 
elif sock == sys.stdin: 
    data = sock.readline() 
    for s in input: 
     if s not in (server_socket, sys.stdin): 
      s.send(data) 
else: 
    ... 
+0

vì vậy tôi nên có một câu lệnh if mà tay một cái gì đó từ keyobard như: nếu vớ == stdin: msg = sys .stdin.readline() server_socket.send() prompt() – jtd92

+0

chắc chắn, bất kỳ cách nào để giữ cho xử lý 'stdin' riêng biệt – cmd

+0

alright bây giờ tôi nhận được lỗi đường ống bị hỏng [Errno 32] từ server_socket.send ('\ r : '+ msg). Tôi có cần kết nối với máy khách từ máy chủ không? Cảm ơn – jtd92

0

Tôi đã thử các loại tương tự của chương trình từ liên kết được cung cấp dưới đây, nhưng vấn đề đã được select() đã không được hỗ trợ trong các cửa sổ hệ điều hành.

File objects on Windows are not acceptable, but sockets are. On 
Windows, the underlying select() function is provided by the WinSock 
library, and does not handle file descriptors that don’t originate 
from WinSock. 

http://www.binarytides.com/code-chat-application-server-client-sockets-python/