【问题标题】:Issue with Python sockets between client and server客户端和服务器之间的 Python 套接字问题
【发布时间】:2019-11-22 16:48:58
【问题描述】:

试图找出问题所在让我头疼。我有一个基本的客户端和一个服务器,客户端发送一个请求,服务器回复一个答案,问题是服务器没有发送他期望的内容。

非常感谢任何可以帮助我的人,非常感谢。 这是代码: 客户端代码:

def main():
    import socket
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    my_socket.connect(('127.0.0.1',8000))
    info = input(r"Enter what you want to send to the server: ")
    while info != "exit":
        my_socket.send(info.encode('ascii'))
        if info != "EXIT":
            data_from_server = my_socket.recv(2).decode('ascii')
            data_from_server = my_socket.recv(int(data_from_server))
            print(data_from_server.decode('ascii'))
            info = input("Enter what you want to send to the server: ")
        else:
            info = "exit"
    my_socket.close()


if __name__ == '__main__':
    main()

这是服务器代码:

import socket
import sys
import time
from random import randrange
SERVER_NAME = "010101"

def number_of_elements(str):
    num = 0
    for e in str:
        num += 1
    return num


def main():
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind(('0.0.0.0',8000))
    while True:
        server_socket.listen(1)
        client_socket, client_adresss = server_socket.accept()
        client_request = client_socket.recv(4)
        while client_request != b'EXIT':
            if client_request == b'TIME':
                num_of_chars = number_of_elements(time.ctime())
                client_socket.send(str(num_of_chars).encode('ascii'))
                client_socket.send(time.ctime().encode('ascii'))
            elif client_request == b'NAME':
                num_of_chars = number_of_elements(SERVER_NAME)
                client_socket.send(str(num_of_chars).encode('ascii'))
                client_socket.send(SERVER_NAME.encode('ascii'))
            elif client_request == b'RAND':
                num = 2
                client_socket.send(str(num).encode('ascii'))
                random_num = randrange(11)
                client_socket.send(str(random_num).encode('ascii'))
            else:
                s = str(len("Incorrect Command"))
                client_socket.send(s.encode('ascii'))
                client_socket.send(b"Incorrect Command")
            try:    
                client_request = client_socket.recv(4)
            except:
                client_request = b"EXIT"
        client_socket.close()
    server_socket.close()





if __name__ == '__main__':
  main()

这是一个例子

【问题讨论】:

  • “效果不好”是什么意思?连接不可靠吗?还是连接后有其他问题?
  • 确实可以连接,问题出在请求上,我添加了一张照片作为示例。当客户端向服务器请求“TIME”时,首先发送答案有多少字节,然后他应该发送时间,但是它没有按预期工作。

标签: python sockets server client


【解决方案1】:

这个电话:

client_request = client_socket.recv(4)

表示您要求 4 个字节。但是基于 TCP 的行为,套接字库可以并且将提供更少的内容。而且您的代码没有检查实际收到的字节数。

将您的服务器编码为一次只接收 1 个字节。和/或准备好多次调用recv 并将字节数累积到顺序缓冲区中,直到收到预期的数字。

【讨论】:

  • 您好,感谢您的回复,我写这个调用是因为客户端和服务器使用我发明的协议,这意味着客户端应该只发送这个选项:TIME、RAND、NAME、EXIT。它们都有 4 个字节。如果客户端发送超过 4 个字节,我不处理它们,只处理前四个。
  • 但这不是 TCP 的工作原理。 TCP 是流协议,而不是消息协议。 Internet 上的 IP 分段、TCP 分段和打嗝会导致您的应用程序定义的“消息”被分解为不同的数据包。如果套接字层只收到了最初发送的部分字节,它会很高兴地将它拥有的内容返回给调用者——即使调用者请求的字节数比实际接收到的多。这样做,输入telnet 127.0.0.1 8000 并尝试在终端窗口中输入NAME。您的服务器一次只会收到一个字符。
  • 至少,更改您的代码以使用MSG_WAITALL 标志(如果在您的平台上可用)。
  • 您好,正如您所说,我已将服务器更改为一次只接收一个字节。但是,在我向服务器发送第二个请求后,客户端卡住了。这是我添加的内容: while True: data = client_socket.recv(1) client_request += data if not data: break 但我认为它并没有退出 while 循环,我已将其添加到 try 部分。
猜你喜欢
  • 1970-01-01
  • 2021-03-31
  • 1970-01-01
  • 2014-04-05
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
  • 2016-12-21
相关资源
最近更新 更多