【问题标题】:Server socket application turns into infinite loop when trying to break the "receive" loop in Python 3尝试打破 Python 3 中的“接收”循环时,服务器套接字应用程序变成无限循环
【发布时间】:2019-11-14 22:30:33
【问题描述】:

我在 Python 3 中创建了一个聊天服务器。它与客户端建立连接,等待来自客户端的消息,打印消息并将消息保存到 txt 文件。当客户端发送消息 b'/dc' 时,客户端关闭连接,服务器应该中断循环。相反,客户端正常关闭,但服务器循环无限地在屏幕上打印一条空消息。

服务器:

import socket
import sys
import os
import optparse

def createServer(port):

    # create a TCP socket
    sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # bind the socket to the port
    server_address = ('localhost', port)
    print("starting up on {} port {}".format(*server_address))
    sck.bind(server_address)

    # put the socket into server mode
    sck.listen(5)

    return sck


def runServer(sck, conn, client, logs):

    # server loop
    while True:
        data = conn.recv(1024)
        if data != b'/dc':
            message = client[0] + ': ' + data.decode() + '\n'
            print(message)
            logs.write(message)
        else:
            conn.close()
            break


def main():

    # option to set port when launching the server
    parser = optparse.OptionParser("Usage: pyhon3 server.py -p <server port>")
    parser.add_option('-p', dest='port', type='int', help="specify target port")
    (options, args) = parser.parse_args()
    port = options.port

    if port == None:
        print(parser.usage)
        exit(0)

    # create server logs
    logs = open('./logs.txt', 'a+')

    # create the socket
    sck = createServer(port)


    # wait for connection and start thread
    conn, client = sck.accept()
    runServer(sck, conn, client, logs)


if __name__ == '__main__':
    main()

客户:

import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect the socket to the port where the server is listening
server_address = ('localhost', 10000)
print('connecting to {} port {}'.format(*server_address))
sock.connect(server_address)

while True:

    # Send data
    message = bytes(input('> '), 'utf8')
    if message != b'/dc':
        print('sending {!r}'.format(message))
        sock.sendall(message)
    else:
        break

sock.close()

客户端输出:

connecting to localhost port 10000
> test
sending b'test'
> 123
sending b'123'
> /dc

服务器输出:

127.0.0.1: test

127.0.0.1: 123

127.0.0.1: 

127.0.0.1: 

127.0.0.1: 

127.0.0.1: 

127.0.0.1: 
...

【问题讨论】:

  • 我很确定您显示的代码不是您正在运行的代码。每当客户端发送除/dc 以外的其他内容时,您显示的代码将退出(仅在data == b'/dc' 时写入消息)并且客户端永远不会发送/dc(在/dc 上退出并且不将其发送到服务器) .这不仅来自代码分析,还来自实际运行代码。
  • @SteffenUllrich 你说得对,我编辑了它。编辑后的代码会运行无限循环。

标签: python python-3.x sockets


【解决方案1】:
    if data != b'/dc':
        message = client[0] + ': ' + data.decode() + '\n'
        print(message)
        logs.write(message)
    else:
        conn.close()
        break

这期望客户端发送/dc 以退出循环。但是客户端永远不会发送/dc,因为它会在输入/dc时退出循环并关闭套接字,并且不会在套接字关闭之前发送/dc

if message != b'/dc':
    print('sending {!r}'.format(message))
    sock.sendall(message)
else:
    break

如果在客户端关闭,服务器将recv 和空字符串。一个空字符串是!= b'/dc',这意味着它匹配打印消息而不是关闭连接并退出循环的条件

【讨论】:

    【解决方案2】:

    在您的服务器循环中,在 if 语句下,您在收到 b'/dc' 时打印消息,但您永远不会关闭连接。在 if 段的末尾应该有一个 conn.close() 语句。希望这可以帮助!祝你好运!

    【讨论】:

    • 感谢您的评论!但我犯了一个错误。 if 语句应该改为“if data != b'/dc':”。我会编辑它。如果服务器收到 b'/dc',它应该关闭,因此 else 会关闭连接并中断循环(理论上它不会,因此我的无限循环问题)。
    • 是的,这更有意义。我想知道为什么你需要 if 语句和 else 语句来关闭连接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多