【问题标题】:Python socket server: can't compare input from clientPython套接字服务器:无法比较来自客户端的输入
【发布时间】:2017-06-21 18:39:57
【问题描述】:

我正在练习在 python 上构建一个套接字服务器。我目前在我的 linux mint 系统上本地运行它,并使用telnet localhost 20000 对其进行测试。

这个想法很简单。现在,我希望客户端(我自己)向服务器发送一条“hello”消息,服务器在该服务器上回复另一个“hello”消息。然后客户端可以发送任何服务器没有响应的消息,直到客户端说“再见”。然后服务器响应另一个“再见”,并且套接字关闭。

我通过以下方式实现了这一点(在 python 3 中):

  1 from socket import *
  2 serverPort = 20000
  3 serverSocket = socket(AF_INET, SOCK_STREAM)
  4 serverSocket.bind(('', serverPort))
  5 serverSocket.listen(1)
  6 
  7 print('The echo server is ready to receive')
  8 while 1:
  9     connectionSocket, addr = serverSocket.accept()
 10     print('Processing client ', addr)
 11     sentence = ""
 12 
 13     try:
 14         sentence = connectionSocket.recv(1024)
 15         while sentence != "hello":
 16             sentence = connectionSocket.recv(1024)
 17         connectionSocket.send("hello")
 18 
 19         sentence = connectionSocket.recv(1024)
 20         while sentence != "bye":
 21             sentence = connectionSocket.recv(1024)
 22         connectionSocket.send("bye")
 23     except error:
 24         pass
 25 
 26     print('Client closed ', addr)
 27     connectionSocket.close()

这是一个非常简单的程序,我在其中找不到任何错误,所以看到它不起作用我很惊讶。当我在使用python3 server.py 运行服务器并通过telnet localhost 20000 建立连接后输入“hello”时,我根本没有得到任何响应。我一开始以为问题出在第15行的相等性测试,于是我用prints测试了一些东西,而不是“hello”服务器收到的消息是:b'hello\r\n。我理解 \n,因为我在“hello”消息后输入 Enter,但我不清楚为什么会出现 b' 和 \r。

您知道这里的问题是什么以及如何解决吗?在堆栈溢出的其他示例中,字符串比较工作正常,所以我不知道为什么它不适合我。

提前致谢!

更新: 我现在使用 nc 而不是 telnet,并将每次出现的 connectionSocket.recv(1024) 都更改为 str(connectionSocket.recv(1024), 'utf-8')。服务器现在得到了正确的字符串,但它仍然没有向我回显“hello”,也没有在我输入“bye”时关闭套接字。

【问题讨论】:

  • b' 是因为套接字产生字节,而不是字符串。另外,请尝试使用 nc 而不是 telnet,以避免不得不处理 telnet 协议添加的额外字节。
  • 好的,但我认为来自套接字的 recv 方法返回了一个字符串?我怎样才能让句子只是输入的字符串,所以我可以将它与“hello”进行比较?
  • 谢谢,我马上试试

标签: python-3.x sockets server


【解决方案1】:

使用 netcat 代替 telnet 以避免 telnet 协议字节。 像这样:nc localhost 20000 然后输入您的输入。

另外,在 Python 3 中,socket I/O 始终是字节,例如参见 https://docs.python.org/3/library/socket.html#socket.socket.recv 所以你必须与 b'hello' 进行比较(或先将字节解码为字符串)

【讨论】:

  • 谢谢,但还是不行。我现在使用 nc,并将每次出现的 connectionSocket.recv(1024) 更改为 str(connectionSocket.recv(1024), 'utf-8')。服务器现在得到了正确的字符串,但它仍然没有向我回显“hello”,也没有在我输入“bye”时停止。
  • 你调试过吗?要么在 sock.recv() 之后的行上放置一个断点,要么打印你在那里收到的内容。您将看到(如果您通过 netcat 使用手动输入!)接收到的字节将是 'hello\n',它仍然包含您将在 netcat 控制台中输入的换行符。如果您使用sock.makefile() 并从中读取内容,就好像它是一个普通文件一样,也许对您来说会更容易?而不是处理原始的 recv 调用
  • 谢谢!我解决了!我接受了你的回答。如果您也可以投票赞成这个问题,将不胜感激:)
  • 您使用了两个建议中的哪一个来使其发挥作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
  • 2019-04-13
  • 2014-11-05
  • 1970-01-01
  • 2016-07-17
  • 1970-01-01
相关资源
最近更新 更多