Python非阻塞点对点聊天socket.error:[Errno 32]断管

时间:2013-09-13 11:42:26

标签: python sockets asyncsocket

您好,我为服务器和客户端之间的点对点聊天编写简单的聊天程序。 此代码适用于客户端,客户端可以发送消息,服务器可以重新获取该消息。但对于服务器端,当我想发送消息时,我在第40行有错误

  File "server.py", line 40, in <module>
    newSocket.send('\r<Server>: ' + msg)
    socket.error: [Errno 32] Broken pipe

和服务器崩溃。

服务器:

import socket
import os
import select
import sys

def prompt():
    sys.stdout.write('Server :  ')
    sys.stdout.flush()

try:
    newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    newSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except:
    print 'socket Error'
    sys.exit(1)

newSocket.bind(('127.0.0.1', 8000))
newSocket.listen(5)

input_list = [newSocket, sys.stdin]

print 'Chat Program'
prompt()

while True:

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

    for sock in inputready:

        if sock == newSocket:
            (client, (ip, port)) = newSocket.accept()
            input_list.append(client)
            data = client.recv(2048)
            if data:
                sys.stdout.write(data)

        elif sock == sys.stdin:
            msg = sys.stdin.readline()
            newSocket.send('\r<Server>: ' + msg)
            prompt()

        else:
            data = sock.recv(2048)
            if data:
                sys.stdout.write(data)

newSocket.close()

客户:

import socket
import os
import select
import sys

def prompt():
   sys.stdout.write('Client ')
   sys.stdout.flush()


try:
    newSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    newSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except:
    print 'socket Error'
    sys.exit(1)


newSocket.connect(('127.0.0.1', 8000))

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

while 1:

    socket_list = [sys.stdin, newSocket]

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

    for sock in read_sockets:
        if sock == newSocket:
            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()
            newSocket.send('\r<Client>: ' + msg)
            prompt()

2 个答案:

答案 0 :(得分:1)

您应该使用accept()。当您尝试使用newSocket时,似乎.send()尚未准备好输出。

答案 1 :(得分:0)

我将服务器代码更改为此问题已解决:

import socket
import select
import sys

CONNECTION_LIST = []
RECV_BUFFER = 4096
PORT = 1245

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind(('0.0.0.0', PORT))
server_socket.listen(5)

CONNECTION_LIST.append(server_socket)
CONNECTION_LIST.append(sys.stdin)


print 'Chat server Started on port ' + str(PORT)


def broadcast_data(sock, message):

    for socket in CONNECTION_LIST:
        if socket != server_socket and socket != sock and socket != sys.stdin:
            try:
                socket.send(message)
            except:
                socket.close()
                CONNECTION_LIST.remove(socket)

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

prompt()

while True:
    read_sockets, write_sockets, error_sockets = select.select(CONNECTION_LIST, [], []) # NON_blocking I/O with 0

    for sock in read_sockets:
        if sock == server_socket:
            # new Connection
            sockfd, addr = server_socket.accept()
            CONNECTION_LIST.append(sockfd)
            print 'Clinet (%s, %s) connected ' % addr
            broadcast_data(sockfd, "[%s:%s] entered room" % addr)
        elif sock == sys.stdin:
            msg = sys.stdin.readline()
            broadcast_data(sock, 'Server > ' + msg)
            prompt()
        else:
            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:
                    print "\r" + '<' + str(sock.getpeername()) + '>' + 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