Python 在自己的线程上交谈,并通过队列或其他方式与主线程通信。我选择在单个线程中使用

Python 在自己的线程上交谈,并通过队列或其他方式与主线程通信。我选择在单个线程中使用,python,python-2.7,sockets,server,client,Python,Python 2.7,Sockets,Server,Client,select.select()允许您等待多个类似文件的对象进行I/O。它接受三个列表,并返回三个列表。第一个list参数包含您感兴趣读取的类似文件的对象。第一个返回的列表将包含其中的一个子集,其中包含要读取的数据。第二个列表参数/返回列表对于可写文件的行为类似,第三个用于错误条件。select.select()的第四个参数是超时,如果达到此超时并且没有文件准备好读/写/出错,则调用将返回三个空列表 我用它来处理来自stdin的用户输入和到达套接字的数据 不过,在这个答案中,“>”的插入有点错误

select.select()
允许您等待多个类似文件的对象进行I/O。它接受三个列表,并返回三个列表。第一个list参数包含您感兴趣读取的类似文件的对象。第一个返回的列表将包含其中的一个子集,其中包含要读取的数据。第二个列表参数/返回列表对于可写文件的行为类似,第三个用于错误条件。
select.select()
的第四个参数是超时,如果达到此超时并且没有文件准备好读/写/出错,则调用将返回三个空列表

我用它来处理来自stdin的用户输入和到达套接字的数据

不过,在这个答案中,“>”的插入有点错误

import socket
import time
import sys
import select

HOST = '127.0.0.1'
PORT = 4444
NICKNAME = 'NICKNAME_HERE' + ' >'

def connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))


    while True:
        sys.stdout.write(">")
        sys.stdout.flush()
        readable, writable, errors = select.select([sys.stdin, s], [], [])
        if sys.stdin in readable:
            message = sys.stdin.readline()
            nickandmessage = NICKNAME + message
            s.send(nickandmessage)

        if s in readable:
            data = s.recv(1024)
            # TODO: check if socket was closed and exit (data == "")
            print(data)
            # CHANGED: this was to remove echos? the server fixes that
            # if NICKNAME not in data:
            #     print data

connect()

由于某种原因,客户端无法工作。当我尝试以消息开头时,在第18行出现错误:“尝试在非套接字的对象上执行操作。”有什么想法吗?您正在哪个平台上尝试此操作?Windows、Linux或OSX?我的主机是Linux笔记本电脑,它可以在Linux上工作,但不能在Windows上工作。这在Windows上能起作用吗?显然,
select.select()
调用在仅Windows的套接字上不支持类似文件的对象。更新的答案包括这一点。我以前不知道对不起。不幸的是,我不知道如何在Windows上解决这个问题,缺少等待用户输入或使用win32 api的线程(msvcrt.kbhit()看起来很有希望)。它在linux上工作,所以我接受答案。谢谢你的帮助,我会设法弄明白的。客户端由于某种原因无法工作,我在第18行出现了一个错误,当我尝试以以下消息开始时:“尝试在非套接字的对象上进行操作。”有什么想法吗?你在什么平台上尝试此操作?Windows、Linux或OSX?我的主机是Linux笔记本电脑,它可以在Linux上工作,但不能在Windows上工作。这在Windows上能起作用吗?显然,
select.select()
调用在仅Windows的套接字上不支持类似文件的对象。更新的答案包括这一点。我以前不知道对不起。不幸的是,我不知道如何在Windows上解决这个问题,缺少等待用户输入或使用win32 api的线程(msvcrt.kbhit()看起来很有希望)。它在linux上工作,所以我接受答案。谢谢你的帮助,我会设法弄明白的。
import socket
import time

HOST = '127.0.0.1'
PORT = 4444
NICKNAME = 'NICKNAME_HERE' + ' >'


def connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))

    while True:
        message = raw_input("> ")
        nickandmessage = NICKNAME + message
        s.send(nickandmessage)
        data = s.recv(1024)
        if NICKNAME not in data:
            print data

connect()
#!/usr/bin/python
import socket
from threading import Thread, Lock

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 4444))

# CHANGED:
# threading.Lock() to lock access to the connections list
lock = Lock()
# hold open connections in a list
connections = []

def get_data(s, conn):
    data = conn.recv(1024)
    print conn, data, "\n"
    return data;

def send_data(sender, data):
    with lock:
        count = 0
        for conn in connections:
            if conn == sender:
                # don't echo back to the originator
                continue
            try:
                print(data)
                conn.send(data)
                count += 1
            except socket.error:
                # TODO: add better error handling
                pass

    # CHANGED: show num clients sent to
    print "Data sent to %d clients \n" % count

def listen():
    while True:
        conn, addr = s.accept()

        # CHANGED: add connection to connections list
        with lock:
            connections.append(conn)

        print addr, " connected \n"
        while True:
            data = get_data(s, conn)
            # CHANGED: handle close
            if not data:
                break
            send_data(conn, data)

        # CHANGED: remove connection from connections list and close it
        with lock:
            connections.remove(conn)

        conn.close()

s.listen(5)
for i in range(5):
    Thread(target = listen).start()
import socket
import time
import sys
import select

HOST = '127.0.0.1'
PORT = 4444
NICKNAME = 'NICKNAME_HERE' + ' >'

def connect():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((HOST, PORT))


    while True:
        sys.stdout.write(">")
        sys.stdout.flush()
        readable, writable, errors = select.select([sys.stdin, s], [], [])
        if sys.stdin in readable:
            message = sys.stdin.readline()
            nickandmessage = NICKNAME + message
            s.send(nickandmessage)

        if s in readable:
            data = s.recv(1024)
            # TODO: check if socket was closed and exit (data == "")
            print(data)
            # CHANGED: this was to remove echos? the server fixes that
            # if NICKNAME not in data:
            #     print data

connect()