gpt4 book ai didi

python - 尝试对不是套接字的东西进行操作(尝试修复很多)

转载 作者:可可西里 更新时间:2023-11-01 10:04:40 25 4
gpt4 key购买 nike

在你说这是重复之前,我已经看了很多关于这个的文章,但仍然无法修复它。我正在制作一个非常基本的聊天客户端和服务器 python 程序。

然而,在通过我的客户端连接后,它在服务器控制台上显示“已连接”,但在聊天时立即断开连接并显示错误“OSError: [WinError 10038]套接字'

聊天

def chat_client():
if(len(sys.argv) not in (3, 4)):
print("Usage: python chat_client.py <hostname> <port> <optional-username>\n")
sys.exit()

host = sys.argv[1]
port = int(sys.argv[2])
username = ""
if len(sys.argv) == 4:
username = sys.argv[3]
else:
username = "Guest"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)

# Connect to remote host
try:
s.connect((host, port))
except:
print("Unable to connect")
sys.exit()

print("Connected to remote host. You can start sending messages")
print("*** Press Control-C to log off ***\n")
sys.stdout.write("[" + username + "] ")
sys.stdout.flush()

while True:
socket_list = [sys.stdin, s]

try:
# Get the list sockets which are readable
ready_to_read, ready_to_write, in_error = select.select(socket_list, [], [])
except KeyboardInterrupt:
system("clear")
sys.stdout.write("\nYou have logged off\n")
sys.stdout.flush()
sys.exit()

服务器

HOST = ""
SOCKET_LIST = []
RECV_BUFFER = 4096
PORT = 9009
CONVERSATION = ""

def chat_server():
global CONVERSATION
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)

# Add server socket object to the list of readable connections
SOCKET_LIST.append(server_socket)

print("Chat server started on port " + str(PORT))

while True:
try:
# Get the list sockets which are ready to be read through select
# 4th arg, time_out = 0 : poll and never block
ready_to_read, ready_to_write, in_error = select.select(SOCKET_LIST, [], [], 0)

for sock in ready_to_read:
# A new connection request recieved
if sock == server_socket:
sockfd, addr = server_socket.accept()
SOCKET_LIST.append(sockfd)
print("Client (%s, %s) connected" % addr)

broadcast(server_socket, sockfd, "[%s, %s] entered our chatting room\n" % addr)
# A message from a client, not a new connection
else:
# Process data recieved from client
try:
# Recieving data from socket
data = sock.recv(RECV_BUFFER)
if data:
# there is something in the socket
# broadcast(server_socket, sock, "\r" + '[' + str(sock.getpeername()) + '] ' + data) # old
broadcast(server_socket, sock, "\r" + data)
else:
# Remove the socket that's broken
if sock in SOCKET_LIST:
SOCKET_LIST.remove(sock)

# at this stage, no data probably means the connection has been broken
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
except:
broadcast(server_socket, sock, "Client (%s, %s) is offline\n" % addr)
continue
except KeyboardInterrupt:
server_socket.close()
sys.exit()

server_socket.close()


# broadcast chat messages to all connected clients
def broadcast(server_socket, sock, message):
for socket in SOCKET_LIST:
# send the message only to peer
if socket != server_socket and socket != sock:
try:
socket.send(message)
except:
# Broken socket connection
socket.close()
# Broken socket, remove it
if socket in SOCKET_LIST:
SOCKET_LIST.remove(socket)

if __name__ == "__main__":
sys.exit(chat_server())

最佳答案

来自 selectdocumentation :

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.

这排除了使用 sys.stdin

备选方案:

  • 使用Cygwin (无需修改代码)
  • 创建一个等待 sys.stdin 的线程(如 here )
  • 走完整的 Windows 路线并使用 WaitForMultipleObjects
  • 使用一些库来抽象这些细节,我喜欢 libuv但还没有在 python 中使用它

另一件事:不要在无限循环中使用零超时的select。这种忙碌的等待实在是太低效了。而是忽略超时让 select 阻塞直到描述符准备好。

关于python - 尝试对不是套接字的东西进行操作(尝试修复很多),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35889267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com