【问题标题】:socket-based simple python chat program基于socket的简单python聊天程序
【发布时间】:2013-05-13 20:29:18
【问题描述】:

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

服务器.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()

客户端.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()

【问题讨论】:

  • 这不是点对点,因为它有一个服务器

标签: python sockets chat


【解决方案1】:

嗯,在你的服务器上你正在做(缩写)

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

【讨论】:

  • 所以我应该有一个 if 语句,它会从 keyobard 传递一些东西,例如: if sock == stdin: msg = sys.stdin.readline() server_socket.send() prompt()
  • 当然,以任何方式保持stdin 处理分开
  • 好吧,现在我从 server_socket.send('\r: ' + msg) 收到损坏的管道错误 [Errno 32]。我需要从服务器连接到客户端吗?谢谢
  • 您想在连接的客户端上发送,而不是在侦听套接字上发送。调整答案以显示如何
【解决方案2】:

我从下面提供的链接中尝试了类似类型的程序,但问题是 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/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    相关资源
    最近更新 更多