基于socket的简单python聊天程序

时间:2013-05-13 20:29:18

标签: python sockets chat

我正在编写一个简单的基于套接字的聊天程序,它允许服务器向客户端发送和接收消息。客户端可以向服务器发送消息,但是当我尝试从服务器发送消息时,它崩溃说“文件”对象具有属性“recv”。

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()

2 个答案:

答案 0 :(得分: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应使用read而不是recv。下面的结构对我来说最有意义。

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:
    ...

答案 1 :(得分:0)

我从下面提供的链接尝试了类似类型的程序,但是在Windows操作系统中不支持select()的问题。

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/