【问题标题】:"IndexError: string index out of range" when loop is already ended! - Python 3循环结束时出现“IndexError:字符串索引超出范围”! - 蟒蛇 3
【发布时间】:2014-11-27 22:31:16
【问题描述】:

我最近正在研究套接字,试图让它们在 Windows 内部的 Python 脚本 (Python3) 中工作。

这里是服务器端的 Python 脚本。

import socket
import time

MSGLEN = 2048
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 8000))
server.listen(1)

while 1:
    #accept connections from outside
    (clientsocket, address) = server.accept()

    chunks = []
    bytes_recd = 0
    while bytes_recd < MSGLEN:

        chunk = clientsocket.recv(min(MSGLEN - bytes_recd, 2048)) #should enough this row without checks if transmission guaranteed inside buffer dimension
        #print(chunk)
        #i=0
        chunk = chunk.decode()
        bytes_recd = bytes_recd + len(chunk)
        chunks.append(chunk)
        for i in range(bytes_recd):
            if(chunk[i] == "_"):
                print("Breaking(_Bad?)")
                break

        buff_str = chunk[:i]
        print(buff_str)
        if chunk == '':
            print("Server notification: connection broken")
            break


    mex = ''.join(chunks)
    print("Server notification: \n\tIncoming data: " + mex)
    i=1;
    while i==1:
        chunk = clientsocket.recv(128)
        chunk = chunk.decode()
        if chunk == '':
            i = 0

    totalsent = 0
    msg = "Server notification: data received"
    while totalsent < MSGLEN:
        sent = clientsocket.send(bytes(msg[totalsent:], 'UTF-8'))
        if sent == 0 :
            print ("Server notification: end transmitting")
            break
        totalsent = totalsent + sent

我正在检查何时收到“_”并在其中做出决定。这是因为我正在使用阻塞套接字。你应该忘记最后一部分和整个程序功能,因为我正在研究它,而有罪的部分就在这里:

        for i in range(bytes_recd):
        if(chunk[i] == "_"):
            print("Breaking(_Bad?)")
            break

    buff_str = chunk[:i]

发生了一些奇怪的事情:检查工作正常,并通过在正确的索引值处打印其余部分来打破循环。但!出现了这个狂野且明显无意义的错误:

>>>
    Breaking(_Bad?), i:  2
13
Traceback (most recent call last):
  File "C:\Users\TheXeno\Dropbox\Firmwares\Altri\server.py", line 24, in <module>
    if(chunk[i] == "_"):
IndexError: string index out of range

从控制台输出可以看出,它找到“_”之前的数字,在本例中是字符串“13”,位于i = 2,符合套接字接收字符串格式:“charNumber_String”。但似乎一直在计数,直到退出边界。

编辑:我不会重命名变量,但下次最好使用改进的名称,而不是“块”和“块”。

【问题讨论】:

    标签: python sockets loops python-3.x indexoutofboundsexception


    【解决方案1】:

    尝试:

    for i, chunk in enumerate(chunks):
        if(chunk == "_"):
            print("Breaking(_Bad?)")
            break
    

    这样你就永远不会越界。所以少了一个错误:)

    【讨论】:

    • 我明白你在说什么。我修改了它:chunk = chunk.decode() bytes_recd = bytes_recd + len(chunk) chunks.append(chunk) for i, chunk in enumerate(chunks): if(chunk[i] == "_"): print("Breaking(_Bad?), i: ", i) break buff_str = chunk[:i] 它没有改变。同样的IndexError。
    • ...而且没有找到这个修改的索引。
    • 您只更改了我建议的部分内容,因此您仍然会出错。目前还不清楚,你想实现什么,我怀疑你的算法模型中只是有逻辑错误(或者可能只是不认识appendextend 之间的区别)。尝试将您的问题简化为仅几行相关的行,对常量数据进行操作(使用序列存根您的套接字流)。
    【解决方案2】:

    让我们看看这段代码:

    while bytes_recd < MSGLEN:
        chunk = clientsocket.recv(min(MSGLEN - bytes_recd, 2048)) 
        chunk = chunk.decode()
        bytes_recd = bytes_recd + len(chunk)
        chunks.append(chunk)
        for i in range(bytes_recd):
            if(chunk[i] == "_"):
                print("Breaking(_Bad?)")
                break
    

    假设您读取了 100 个字节,并假设解码块的长度与编码块的长度相同。 bytes_recd 将是 100,你的 for 循环从 0 变为 99,一切都很好。

    现在您又读取了 100 个字节。 chunk 又是 100 字节长,chunks(带有“s”)是 200 字节。 bytes_recd 现在是 200。您的 for 循环现在从 0 变为 199,并且您正在检查 chunk[i]chunk 只有 100 字节长,所以当我超过 99 时,你会得到错误。

    也许您打算比较chunks[i](带有“s”)?

    【讨论】:

    • 我在第一次阅读后几乎通过避开循环来修复,考虑到您的观察。这是有效的,因为字符串的第一部分只是总接收部分的数字(包括数字本身的字符)。但这仅在我收到至少与到达 '_' char 的字节数相同的情况下才有效,即 3 到 4 个字节。如果这不能保证,我需要找到更好的东西。有可以保证的最小收货尺寸吗?
    • 现在我将处理可以接收任意大小的情况,因此继续尝试接收直到收到标记字符。在这一点上,原来的问题已经解决或者 - 从未存在过。
    猜你喜欢
    • 2018-03-03
    • 2020-11-18
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多