Python 创建聊天室-出现错误[WinError 10038]尝试对非套接字的内容执行操作

Python 创建聊天室-出现错误[WinError 10038]尝试对非套接字的内容执行操作,python,Python,我创建了一个服务器/客户端代码,使用套接字编程和多线程创建聊天室。我遇到了一个错误,我似乎不理解服务器代码是否正常工作,但我面临客户端代码和idk的问题,为什么它说它不是套接字。如果能在这方面得到任何帮助,我将不胜感激 服务器代码 import socket import sys from _thread import * server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SO

我创建了一个服务器/客户端代码,使用套接字编程和多线程创建聊天室。我遇到了一个错误,我似乎不理解服务器代码是否正常工作,但我面临客户端代码和idk的问题,为什么它说它不是套接字。如果能在这方面得到任何帮助,我将不胜感激

服务器代码

import socket
import sys
from _thread import *

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# checks whether sufficient arguments have been provided
# if len(sys.argv) != 3:
#     print ("missing arguments enter: <IP address> <port number>")
#     exit()

# first argument from command prompt is IP address
IP_address = '127.0.0.1'
# second argument from command prompt is port number
Port = 12000
# binds the server to an entered IP address and specified port number.
server.bind((IP_address, Port))

# listens for 10 active connections
server.listen(10)
list_of_clients = []

def clientthread(conn, addr):
    # sends a message to the client whose user object is conn
    conn.send("Welcome to Network Programming chatroom!")
    # broadcast to other that a new client has joined 
    message_to_send = "<" + addr[0] +", " + str(addr[1]) + "> joined"
    broadcast(message_to_send, conn)
    while True:
        try:
            message = conn.recv(4096)
            if message:
                # prints the message and address of the user who just sent the message
                print ("<" + addr[0] + ", " + str(addr[1]) + ">: " + message)
                # call broadcast function to send message to all other clients
                message_to_send = "<" + addr[0] +", " + str(addr[1]) + ">: " + message
                broadcast(message_to_send, conn)
            else:
                ''' message have no content if the connection is broken, then 
                send message to others and remove the connection'''
                print("connection : <" + addr[0] + ", " + str(addr[1]) + "> disconnected")
                message_to_send = "<" + addr[0] +", " + str(addr[1]) + "> left"
                broadcast(message_to_send, conn)
                remove(conn)
                break
        except:
            print("error occurred and ignored with: <" + addr[0] +", " + str(addr[1]) + "> connection")
            continue

""" broadcast function is used to broadcast a message to all
clients (but not the sender) """
def broadcast(message, connection):
    for client in list_of_clients:
        if client != connection:
            try:
                client.send(message)
            except:
                client.close()
                # if the link is broken, remove the client
                remove(client)

''' remove function to remove the object from the list of clients '''
def remove(connection):
    if connection in list_of_clients:
        list_of_clients.remove(connection)

print("Welcome to Network Programming chatroom!\nServer is waiting for clients...")
while True:

    """ accepts a connection request and stores two parameters:  
    conn socket object and addr of the connected client"""
    conn, addr = server.accept()

    """ maintains a list to keep track of all available clients in the chatroom"""
    list_of_clients.append(conn)

    # prints the address of the user that just connected
    print (addr[0], addr[1], " joined")
    # creates an individual thread for every client 
    start_new_thread(clientthread,(conn,addr))
conn.close()
server.close()
import socket
import select
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# if len(sys.argv) != 3:
#     print ("missing arguments enter: <IP address> <port number>")
#     exit()
IP_address = '127.0.0.1'
Port = 12000
server.connect((IP_address, Port))
while True:
    # create a list to maintain possible input streams
    sockets_list = [sys.stdin, server]
    """ Two possible inputs scenarios. Either the
    user enters text to send to other clients, or the 
    server is sending a message to the client. """

    """ select system call returns from sockets_list, the stream 
    that is reader for input. So for example, if the server sent a message, then the if condition will hold true below. 
    If the user wants to send a message, the else
    condition will evaluate as true"""
    print("wait on select call...")
    read_sockets, write_sockets, error_sockets = select.select(sockets_list,[],[])
    print("select call returned")
    print("read_sockets: ", read_sockets)
    #print("write_sockets: ", write_sockets)
    #print("error_sockets: ", error_sockets)
    for socks in read_sockets:
        if socks == server:
            message = socks.recv(4096)
            if(len(message) != 0):
                print(message)
            # server sent empty message, print error and leave
            else:
                print("Server is down, join later once it is up!")
                exit()
        else:
            message = sys.stdin.readline()
            server.send(message)
            sys.stdout.write("<You>")
            sys.stdout.write(message)
            sys.stdout.flush()

server.close()
导入套接字
导入系统
从线程导入*
服务器=socket.socket(socket.AF\u INET,socket.SOCK\u流)
server.setsockopt(socket.SOL_socket,socket.SO_REUSEADDR,1)
#检查是否提供了足够的参数
#如果len(sys.argv)!=三:
#打印(“缺少参数输入:”)
#退出()
#命令提示符的第一个参数是IP地址
IP_地址='127.0.0.1'
#命令提示符的第二个参数是端口号
端口=12000
#将服务器绑定到输入的IP地址和指定的端口号。
服务器绑定((IP_地址,端口))
#侦听10个活动连接
服务器。听(10)
客户端列表=[]
def客户端线程(连接,添加):
#向用户对象为conn的客户端发送消息
conn.send(“欢迎来到网络编程聊天室!”)
#广播到新客户端已加入的其他客户端
message\u to\u send=“已加入”
广播(信息发送,康涅狄格州)
尽管如此:
尝试:
message=conn.recv(4096)
如果消息:
#打印刚刚发送消息的用户的消息和地址
打印(“:”+消息)
#调用广播功能向所有其他客户端发送消息
message_to_send=“:”+message
广播(信息发送,康涅狄格州)
其他:
''消息没有内容如果连接断开,则
向其他人发送消息并删除连接“”
打印(“连接:断开”)
message\u to\u send=“left”
广播(信息发送,康涅狄格州)
拆卸(连接)
打破
除:
打印(“发生错误并忽略了:连接”)
持续
“”“广播功能用于向所有用户广播消息。”
客户端(但不是发件人)”“”
def广播(消息、连接):
对于\u客户端列表中的客户端:
如果是客户端!=连接:
尝试:
客户端发送(消息)
除:
client.close()
#如果链接断开,请删除客户端
删除(客户端)
''remove函数从客户端列表中删除对象''
def拆卸(连接):
如果连接位于\u客户端列表\u中:
列出\u个客户端。删除(连接)
打印(“欢迎来到网络编程聊天室!\n服务器正在等待客户端…”)
尽管如此:
“”“接受连接请求并存储两个参数:
连接的客户端“”的conn套接字对象和地址
conn,addr=server.accept()
“”“维护一个列表以跟踪聊天室中所有可用的客户端”“”
列出\u个客户端。附加(连接)
#打印刚刚连接的用户的地址
打印(地址[0],地址[1],“已加入”)
#为每个客户端创建一个单独的线程
启动新线程(clientthread,(conn,addr))
康涅狄格州关闭
server.close()
客户端代码

import socket
import sys
from _thread import *

server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# checks whether sufficient arguments have been provided
# if len(sys.argv) != 3:
#     print ("missing arguments enter: <IP address> <port number>")
#     exit()

# first argument from command prompt is IP address
IP_address = '127.0.0.1'
# second argument from command prompt is port number
Port = 12000
# binds the server to an entered IP address and specified port number.
server.bind((IP_address, Port))

# listens for 10 active connections
server.listen(10)
list_of_clients = []

def clientthread(conn, addr):
    # sends a message to the client whose user object is conn
    conn.send("Welcome to Network Programming chatroom!")
    # broadcast to other that a new client has joined 
    message_to_send = "<" + addr[0] +", " + str(addr[1]) + "> joined"
    broadcast(message_to_send, conn)
    while True:
        try:
            message = conn.recv(4096)
            if message:
                # prints the message and address of the user who just sent the message
                print ("<" + addr[0] + ", " + str(addr[1]) + ">: " + message)
                # call broadcast function to send message to all other clients
                message_to_send = "<" + addr[0] +", " + str(addr[1]) + ">: " + message
                broadcast(message_to_send, conn)
            else:
                ''' message have no content if the connection is broken, then 
                send message to others and remove the connection'''
                print("connection : <" + addr[0] + ", " + str(addr[1]) + "> disconnected")
                message_to_send = "<" + addr[0] +", " + str(addr[1]) + "> left"
                broadcast(message_to_send, conn)
                remove(conn)
                break
        except:
            print("error occurred and ignored with: <" + addr[0] +", " + str(addr[1]) + "> connection")
            continue

""" broadcast function is used to broadcast a message to all
clients (but not the sender) """
def broadcast(message, connection):
    for client in list_of_clients:
        if client != connection:
            try:
                client.send(message)
            except:
                client.close()
                # if the link is broken, remove the client
                remove(client)

''' remove function to remove the object from the list of clients '''
def remove(connection):
    if connection in list_of_clients:
        list_of_clients.remove(connection)

print("Welcome to Network Programming chatroom!\nServer is waiting for clients...")
while True:

    """ accepts a connection request and stores two parameters:  
    conn socket object and addr of the connected client"""
    conn, addr = server.accept()

    """ maintains a list to keep track of all available clients in the chatroom"""
    list_of_clients.append(conn)

    # prints the address of the user that just connected
    print (addr[0], addr[1], " joined")
    # creates an individual thread for every client 
    start_new_thread(clientthread,(conn,addr))
conn.close()
server.close()
import socket
import select
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# if len(sys.argv) != 3:
#     print ("missing arguments enter: <IP address> <port number>")
#     exit()
IP_address = '127.0.0.1'
Port = 12000
server.connect((IP_address, Port))
while True:
    # create a list to maintain possible input streams
    sockets_list = [sys.stdin, server]
    """ Two possible inputs scenarios. Either the
    user enters text to send to other clients, or the 
    server is sending a message to the client. """

    """ select system call returns from sockets_list, the stream 
    that is reader for input. So for example, if the server sent a message, then the if condition will hold true below. 
    If the user wants to send a message, the else
    condition will evaluate as true"""
    print("wait on select call...")
    read_sockets, write_sockets, error_sockets = select.select(sockets_list,[],[])
    print("select call returned")
    print("read_sockets: ", read_sockets)
    #print("write_sockets: ", write_sockets)
    #print("error_sockets: ", error_sockets)
    for socks in read_sockets:
        if socks == server:
            message = socks.recv(4096)
            if(len(message) != 0):
                print(message)
            # server sent empty message, print error and leave
            else:
                print("Server is down, join later once it is up!")
                exit()
        else:
            message = sys.stdin.readline()
            server.send(message)
            sys.stdout.write("<You>")
            sys.stdout.write(message)
            sys.stdout.flush()

server.close()
导入套接字
导入选择
导入系统
服务器=socket.socket(socket.AF\u INET,socket.SOCK\u流)
#如果len(sys.argv)!=三:
#打印(“缺少参数输入:”)
#退出()
IP_地址='127.0.0.1'
端口=12000
服务器连接((IP地址,端口))
尽管如此:
#创建一个列表来维护可能的输入流
套接字\u列表=[sys.stdin,服务器]
“”“两种可能的输入方案。或
用户输入要发送给其他客户端的文本,或
服务器正在向客户端发送消息。”“”
“”“选择从套接字返回的系统调用\u列表,流
例如,如果服务器发送了一条消息,那么下面的if条件将保持为true。
如果用户想要发送消息,则else
条件将评估为true“”
打印(“等待选择呼叫…”)
读插槽,写插槽,错误插槽=选择。选择(插槽列表,[],[])
打印(“选择返回的呼叫”)
打印(“读取插槽:”,读取插槽)
#打印(“写入插槽:”,写入插槽)
#打印(“错误插槽:”,错误插槽)
对于read_插槽中的袜子:
如果socks==服务器:
message=socks.recv(4096)
如果(len(message)!=0):
打印(信息)
#服务器发送了空消息,打印错误并离开
其他:
打印(“服务器已关闭,待服务器启动后再加入!”)
退出()
其他:
message=sys.stdin.readline()
发送(消息)
sys.stdout.write(“”)
系统标准输出写入(消息)
sys.stdout.flush()
server.close()
客户端上的输出

Traceback (most recent call last):
  File "C:/Users/a/Desktop/Network Programming 2/chat-client.py", line 23, in <module>
    read_sockets, write_sockets, error_sockets = select.select(sockets_list,[],[])
OSError: [WinError 10038] An operation was attempted on something that is not a socket
wait on select call...
回溯(最近一次呼叫最后一次):
文件“C:/Users/a/Desktop/networkprogramming 2/chat client.py”,第23行,在
读插槽,写插槽,错误插槽=选择。选择(插槽列表,[],[])
OSError:[WinError 10038]尝试对非套接字的对象执行操作
等待选择呼叫。。。

您将
sys.stdin
放在
sockets\u列表中
。正如错误所说,它不是套接字。在Unix上这没问题,但在Windows上你做不到。

在Windows上怎么做?@THEMISSINGLINK我不知道。可能是某些特定于Win32的函数,这些函数可能在Python中可用,也可能不可用。对不起,我没有在Windows上花太多时间。