7

サーバーがクライアントにメッセージを送受信できるようにする単純なソケットベースのチャットプログラムを作成しています。クライアントはサーバーにメッセージを送信できますが、サーバーからメッセージを送信しようとすると、「ファイル」オブジェクトに属性「recv」があると言ってクラッシュします。

サーバー.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()
4

2 に答える 2

4

さて、あなたのサーバーであなたがやっている(省略)

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)

そのため、何かが入ってきたとき、そうではsys.stdinなくserver_socket、に行きelse、しようとしrecvますが、ソケットではありません。 使用していないstdinはずです。以下のような構造は、私にとって最も理にかなっています。readrecv

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:
    ...
于 2013-05-13T20:38:59.967 に答える
0

以下のリンクから同様のタイプのプログラムを試しましたが、問題はselect()Windows オペレーティング システムではサポートされていませんでした。

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/

于 2015-06-11T10:38:53.987 に答える