【问题标题】:Why is this client-server system not working (simple)为什么这个客户端-服务器系统不工作(简单)
【发布时间】:2019-10-26 20:45:17
【问题描述】:

我正在尝试使一个非常简单的客户端系统变得简单,但我不确定它有什么问题。它应该是一个计算器系统。这是客户端的代码:

import socket

IP = '127.0.0.1'
PORT = 8106

my_socket = socket.socket()
my_socket.connect((IP, PORT))


done = False

while not done:
    command = raw_input("choose a command from [ADD, SUB, MUL, DIV, EXIT]")
    command = command.upper()
    my_socket.send(command)
    data = my_socket.recv(20)
    new_list = data.split(":")
    if command in ["ADD", "SUB", "MUL", "DIV", "EXIT"]:
        if command == "ADD":
            print new_list[0] + "+" + new_list[1] + "=" + new_list[2]
        if command == "SUB":
            print new_list[0] + "-" + new_list[1] + "=" + new_list[2]
        if command == "MUL":
            print new_list[0] + "*" + new_list[1] + "=" + new_list[2]
        if command == "DIV":
            print new_list[0] + "/" + new_list[1] + "=" + new_list[2]
        if command == "EXIT":
            done = True
    else:
        print 'not valid'






这是服务器的代码:

import socket
import random

IP = '0.0.0.0'
PORT = 8106

server_socket = socket.socket()
server_socket.bind((IP, PORT))

server_socket.listen(1)

(client_socket, client_address) = server_socket.accept()


done = False

while not done:
    message = client_socket.recv(4)
    num1 = random.randint(-101, 100)
    print num1
    num2 = random.randint(-101, 100)
    print num2
    if message in ["ADD", "SUB", "MUL", "DIV", "EXIT"]:
        if message == "ADD":
            result = num1 + num2
        elif message == "SUB":
            result = num1 - num2
        elif message == "MUL":
            result = num1 * num2
        elif message == "DIV":
            result = float(num1) / float(num2)
        elif message == "EXIT":
            done = True
        client_socket.send(str(num1) + ":" + str(num2) + ":" + str(result))
    else:
        client_socket.send("0:0:0")

现在,当我运行服务器,然后运行客户端,并多次选择“DIV”时,第一次也可以,但在第二次或第三次尝试时,我收到一条错误消息:

print new_list[0] + "/" + new_list[1] + "=" + new_list[2]
IndexError: list index out of range

我不确定为什么会这样。我试图打印“数据”来尝试解决它,有时数据只是一个数字,例如只有 46,而不是像 46:3:15.333 之类的东西

为什么会这样?

【问题讨论】:

    标签: python python-2.7 server client client-server


    【解决方案1】:

    socket.send 不保证完整数据的打磨。您的应用程序应根据 socket.send 返回值检查发送了多少字节。

    或者只使用socket.sendall 并检查类似的异常:

    try:
        s.sendall(MESSAGE)
    except socket.error:
        # failed to send
    

    参见docs 中的socket.send 和socket.sendall。

    【讨论】:

      【解决方案2】:

      socket.recv(bufsize[, flags]) 方法的文档指定以下内容:

      一次接收的最大数据量由 bufsize 指定。

      关键部分是bufsize 是您可能从一次调用中收到的最大字节数,因此您收到的各个字节字符串在数量和大小上可能并不完全相同,就像你在另一边打电话给send的人一样。

      保证使用默认类型(SOCK_STREAM 即 TCP)创建的套接字的唯一事情是,您的字节流将按照发送时的顺序到达。 p>

      因此,您必须设计一个协议,让客户端和服务器都能识别每条消息的边界。

      您可以通过以下几种方式实现这一目标:

      1. 在消息本身中包含有关每条消息长度的信息。例如,每条消息的第一个字节可以是一个整数,它给出了消息其余部分的长度,给出的最大消息大小为 255(不包括长度前缀)。
      2. 使每封邮件的大小相同。这样您就不必对消息中的长度进行编码 - 您可以继续调用 recv 直到获得预期的字节数。不过,您必须确保可以以相同的格式和长度表示每个数字。

      编辑:根据kirill's answer,您还必须修复发送数据的代码(例如使用sendall)。但是,如果没有进一步的信息,就无法说出这些问题中的哪一个导致了您的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-01
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多