gpt4 book ai didi

sockets - 如何在客户端和服务器(python)中正确关闭套接字

转载 作者:行者123 更新时间:2023-12-03 11:57:10 31 4
gpt4 key购买 nike

我正在用 python 编写 2 个脚本。

  1. 客户端.py
  2. 服务器.py

客户端和服务器之间有一个套接字。场景是这样的:
我有一个客户端要求关闭程序因此它应该通知服务器然后通知另一个客户端,因此我需要关闭从客户端 (1) 到服务器的套接字,然后关闭从服务器到其他客户(想象你自己是一个 2 个人的游戏,其中一个人要求退出游戏)。

我就是这样做的。在 Client.py 中:

# send the request to the server
eNum, eMsg = Protocol.send_all(self.socket_to_server, msg)
if eNum:
sys.stderr.write(eMsg)
self.close_client()
self.socket_to_server.shutdown(socket.SHUT_WR)
exit(0)

然后在Server.py的代码中:

# get the msg from the client that calleds
num, msg = Protocol.recv_all(self.players_sockets[0])

# case of failure
if num == Protocol.NetworkErrorCodes.FAILURE:
sys.stderr.write(msg)
self.shut_down_server()

# case it was disconnected
if num == Protocol.NetworkErrorCodes.DISCONNECTED:
print msg
self.shut_down_server()



technical_win = ("exit" == msg)



# send the msg to the client needed to call
eNum, eMsg = Protocol.send_all(self.players_sockets[1],msg)
if eNum:
sys.stderr.write(eMsg)
self.shut_down_server()

# case end of game (winning or asking to exit)
if technical_win:
self.shut_down_server()

self.shut_down_server() 是:

def shut_down_server(self):

# close socket of one of the player
self.players_sockets[0].shutdown(socket.SHUT_RDWR)
self.players_sockets[0].close()

# close socket of one of the player
self.players_sockets[1].shutdown(socket.SHUT_RDWR)
self.players_sockets[1].close()

# clean up
exit(0)

当服务器发送其他玩家要求退出的消息时,客户端获取它并按照我在开始时展示的方式进行操作。

不幸的是它不起作用,因为当服务器执行代码时:

num, msg = Protocol.recv_all(self.players_sockets[0])

# case of failure
if num == Protocol.NetworkErrorCodes.FAILURE:
sys.stderr.write(msg)
self.shut_down_server()

# case it was disconnected
if num == Protocol.NetworkErrorCodes.DISCONNECTED:
print msg
self.shut_down_server()

它进入第二个 if 并打印 'ERROR - Could not receive a message: timed out.'

我该如何正确解决这个问题?

附言

我正在使用 Linux

最佳答案

看起来您正在寻找的是正常关机。首先,您的代码不起作用,因为您在调用 shutdown 后立即关闭套接字。

规则是,在正常关闭中,双方必须知道关闭并在任何实际关闭套接字之前确认关闭。我只在这个 MSDN page 中找到了引用资料, 即使它被引用在另一个 SO answer 上.

这里是一个简化的演示文稿,如果引用页面可以更好地解释什么(我不知道如何在 SO 中正确格式化表格 :-( ) :

  • 第 1 部分发出 shutdown(socket.SHUT_WR) 以通知它要终止连接,并继续从套接字读取
  • 第 2 部分在套接字上接收文件结束指示(空读取),并且仍然可以发送任何剩余数据 - 然后它依次调用 shutdown(socket.SHUT_WR)
  • 第 1 部分在套接字上接收到文件结尾,并且知道其他部分已使用连接终止
  • 然后两个部分都可以关闭 socket

备注:第 2 部分是否在第 1 部分接收到文件结尾之前实际关闭套接字并不重要,因为第 1 部分已经只是在等待终止指示:不会丢失任何数据

关于sockets - 如何在客户端和服务器(python)中正确关闭套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27746499/

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