Fatal runtime panic upon reading from listner.accept connection. I believe it is failing to read from t connection after I write from a client

huangapple go评论70阅读模式
英文:

Fatal runtime panic upon reading from listner.accept connection. I believe it is failing to read from t connection after I write from a client

问题

谈论容易,英语是我的第二语言,但我会尽力而为。

运行时错误:索引超出范围 [1073741824],长度为 1073741824
这是我具体遇到的错误。我启动服务器,然后在客户端输入用户名后,它就会发生恐慌。只要我不输入用户名,它就正常工作,所以我认为在那之前循环是正常的。我相信它在 read.conn 处中断,因为我在它之后设置了一个断点,但它从未到达那里。
不幸的是,我不确定还要添加什么,但如果不添加更多信息,它将不允许我添加堆栈跟踪。然而,我现在相信这肯定是由于读/写引起的。

以下是我的堆栈跟踪:
panic: 运行时错误:索引超出范围 [65536],长度为 65536

goroutine 6 [running]:
IRC/ClientServer/Messages.getPacket({0xc000132000, 0x10000, 0x0})
/root/go/src/IRC/ClientServer/Messages/rawMessage.go:144 +0x1e
IRC/ClientServer/Messages.ExtractPackets({0xc000132000, 0x10000, 0x10000})
/root/go/src/IRC/ClientServer/Messages/rawMessage.go:114 +0x86
IRC/ClientServer/Server.handleClientRequest({0x5274a8, 0xc000010030})
/root/go/src/IRC/ClientServer/Server/Server.go:60 +0x1f5
created by IRC/ClientServer/Server.ServerStart
/root/go/src/IRC/ClientServer/Server/Server.go:33 +0x157

进程以退出代码 2 结束

这是我的服务器代码:

//Server starts the server
func ServerStart() {
    listener, err := net.Listen("tcp", "0.0.0.0:9999")
    if err != nil {
        log.Fatalln(err)
    }
    defer listener.Close()

    for {
        con, err := listener.Accept()
        if err != nil {
            log.Println(err)
            continue
        }

        // If you want, you can increment a counter here and inject to handleClientRequest below as client identifier
        go handleClientRequest(con)
    }
}

func handleClientRequest(conn net.Conn) {
    defer conn.Close()

    var previousData []byte //holds previous data from for loop

    buffer := make([]byte, 1<<30) //create 1 mb buffer //make sure to zero out when finished
    tracker := Newtrack(15 * time.Second) //create a new tracker and set the timer for 15 seconds

    for {
        _, err := conn.Read(buffer) //read into the buffer
        fmt.Println(err)
        packets, extra, err := Messages.ExtractPackets(append(previousData, buffer...)) //extract the packets

        //print the error
        if err != nil {
            fmt.Println(err)
        }
        previousData = extra //get the extra data if there is any

        //turn the packets into IRC packets
        IRCpackets := make([]Messages.IrcPacket, len(packets)) //create a list of IRC packets len of raw packets
        for index, value := range packets {
            IRC, err := Messages.CreateIrc(value)

            if IRC != nil { //if IRC = nil then err likely does not = nil
                IRCpackets[index] = *IRC //create IRCpackets's for every raw packet
            }
            if err != nil {
                fmt.Println(err)
            }
        }

        //Check if hello has been recieved
        if !tracker.recievedHello() {
            fail, errorType, err := tracker.SetHelloTrack(IRCpackets[0])
            //if it is a failure
            if !fail {
                fmt.Println(err)
                toSend, err := Messages.CreateRaw(Messages.CreateErrorMessage(errorType)) //send the error to client
                if err != nil {
                    fmt.Println(err, "in server hello check")
                }

                _, err = conn.Write(toSend) //Write to the client the error
                if err != nil {
                    fmt.Println(err, "in server hello check 2")
                }
                break //Break the for loop and therefore the connection
            }
        }

        //This is to test it delete later
        if tracker.hello {
            fmt.Println("success")
        }
    }
}

我相信它在 conn.read 处发生恐慌,而且只有在客户端尝试输入用户名后才会发生。

这是我的客户端代码:

func ClientStart() {
    conn, err := net.Dial("tcp", "0.0.0.0:9999")
    if err != nil {
        log.Fatalln(err)
    }
    defer conn.Close()

    //Create the hello message
    //--------
    IRCpack, err := Messages.CreateHello(createUsername())
    packet, err := Messages.CreateRaw(IRCpack)
    if err != nil {
        fmt.Println(err)
    }
    conn.Write(packet)
    //-----
    //The loop
    for {

    }
}

这是可能发生恐慌的 getPacket 函数:

//getPacket grabs a packet from an array and returns a jump and indicates
//if the jump + len(pureraw) > pure raw data then the rest must be extra
//This function assumes you have kept the start deliminator in
//Return of -1 means the rest of the data is extra
func getPacket(data []byte) (int, []byte, error) {

    //This means the rest of the packet may be in rest of buffer
    if data[len(data)] < 9 {
        return -1, data[:], nil
    }

    length := binary.BigEndian.Uint32(data[lenBegin:lenEnd]) //Grab what should be the length

    if length == 0 { //If the length is zero then it has no payload
        return 9, data[:9], nil
    }
    //Check to see if everything is there
    if len(data) < (int(length) + 11) {
        return -1, data[:], nil
    }
    //Make sure the start packet delminator is there
    if data[9] != STARTPACKET {
        return -2, nil, errors.New("start packet delmi error")
    }
    //Now make sure there is an endPacket delminator
    if data[length+11-1] != ENDPACKET { //Leaving in the -1 to show logic and improve readablity
        return -2, nil, errors.New("end packet delmi error")
    }
    return int(length) + 11, data[:length+11], nil // return the length + 11

}

希望这些信息对你有帮助!

英文:

**Talk is cheap and English is my second language but I'll try my best

.runtime error: index out of range [1073741824] with length 1073741824
This is the error I&#39;m getting specifically. I load up the server and then the client once I type in the username on the client side it panics. As long as I don&#39;t type in the username it works fine so I assume it is looping just fine before that. I believe it is breaking at read.conn because I set a break point after it and it never reached there.

I'm unfortunately unsure of what to put more here but it won't allow me to add the stack trace without adding more info . However I now believe it is definitely due to read/write.

Here is my stack trace:
panic: runtime error: index out of range [65536] with length 65536

goroutine 6 [running]:
IRC/ClientServer/Messages.getPacket({0xc000132000, 0x10000, 0x0})
/root/go/src/IRC/ClientServer/Messages/rawMessage.go:144 +0x1e
IRC/ClientServer/Messages.ExtractPackets({0xc000132000, 0x10000, 0x10000})
/root/go/src/IRC/ClientServer/Messages/rawMessage.go:114 +0x86
IRC/ClientServer/Server.handleClientRequest({0x5274a8, 0xc000010030})
/root/go/src/IRC/ClientServer/Server/Server.go:60 +0x1f5
created by IRC/ClientServer/Server.ServerStart
/root/go/src/IRC/ClientServer/Server/Server.go:33 +0x157
Process finished with the exit code 2

Here is my server.

'''

//Server starts the server
func ServerStart() {
listener, err := net.Listen(&quot;tcp&quot;, &quot;0.0.0.0:9999&quot;)
if err != nil {
log.Fatalln(err)
}
defer listener.Close()
for {
con, err := listener.Accept()
if err != nil {
log.Println(err)
continue
}
// If you want, you can increment a counter here and inject to handleClientRequest below as client identifier
go handleClientRequest(con)
}
}
func handleClientRequest(conn net.Conn) {
defer conn.Close()
var previousData []byte //holds previous data from for loop
buffer := make([]byte, 1&lt;&lt;30) //create 1 mb buffer //make sure to zero out when finished
tracker := Newtrack(15 * time.Second) //create a new tracker and set the timer for 15 seconds
for {
_,err := conn.Read(buffer) //read into the buffer
fmt.Println(err)
packets, extra, err := Messages.ExtractPackets(append(previousData,buffer...))//extract the packets
//print the error
if err != nil {
fmt.Println(err)
}
previousData = extra //get the extra data if there is any
//turn the packets into IRC packets
IRCpackets := make([]Messages.IrcPacket, len(packets)) //create a list of IRC packets len of raw packets
for index,value := range packets {
IRC, err := Messages.CreateIrc(value)
if IRC != nil { //if IRC = nil then err likely does not = nil
IRCpackets[index] = *IRC //create IRCpackets&#39;s for every raw packet
}
if err != nil {
fmt.Println(err)
}
}
//Check if hello has been recieved
if !tracker.recievedHello() {
fail,errorType,err := tracker.SetHelloTrack(IRCpackets[0])
//if it is a failure
if !fail {
fmt.Println(err)
toSend, err := Messages.CreateRaw(Messages.CreateErrorMessage(errorType)) //send the error to client
if err != nil { fmt.Println(err,&quot;in server hello check&quot;)}
_, err = conn.Write(toSend) //Write to the client the error
if err != nil {fmt.Println(err, &quot;in server hello check 2&quot;)}
break //Break the for loop and therefore the connection
}
}
//This is to test it delete later
if tracker.hello {
fmt.Println(&quot;success&quot;)
}
}
}

'''
**I believe it panics on conn.read and it only happens after attempting to type in a username in the client.

Here is my client**

'''

func ClientStart() {
conn, err := net.Dial(&quot;tcp&quot;, &quot;0.0.0.0:9999&quot;)
if err != nil {
log.Fatalln(err)
}
defer conn.Close()
//Create the hello message
//--------
IRCpack, err := Messages.CreateHello(createUsername())
packet,err := Messages.CreateRaw(IRCpack)
if	err != nil {fmt.Println(err)}
conn.Write(packet)
//-----
//The loop
for {
}
}

'''

**And here is get packet where it probably panics

'''

//getPacket grabs a packet from an array and returns a jump and indicates
//if the jump + len(pureraw) &gt; pure raw data then the rest must be extra
//This function assumes you have kept the start deliminator in
//Return of -1 means the rest of the data is extra
func getPacket(data []byte) (int, []byte, error) {
//This means the rest of the packet may be in rest of buffer
if data[len(data)] &lt; 9 {
return -1, data[:], nil
}
length := binary.BigEndian.Uint32(data[lenBegin:lenEnd]) //Grab what should be the length
if length == 0 {		//If the length is zero then it has no payload
return 9, data[:9], nil
}
//Check to see if everything is there
if len(data) &lt; (int(length) + 11) {
return -1, data[:], nil
}
//Make sure the start packet delminator is there
if data[9] != STARTPACKET {
return -2, nil, errors.New(&quot;start packet delmi error&quot;)
}
//Now make sure there is an endPacket delminator
if data[length + 11 - 1] != ENDPACKET{ //Leaving in the -1 to show logic and improve readablity
return -2, nil, errors.New(&quot;end packet delmi error&quot;)
}
return int(length) + 11, data[:length + 11], nil // return the length + 11
}

'''

答案1

得分: 2

func getPacket(data []byte) (int, []byte, error) {
...
if data[len(data)-1] < 9 {

len(data) 是数组的大小。由于数组的第一个索引是0,最大索引是 len(data)-1。这意味着 data[len(data)] 尝试访问数组之外的元素,从而导致恐慌。

英文:
func getPacket(data []byte) (int, []byte, error) {
...
if data[len(data)] &lt; 9 {

len(data) is the size of the array. Since the first array index is 0 the maximum index is len(data)-1. This means data[len(data)] is trying to access an element outside the array, thus causing the panic.

huangapple
  • 本文由 发表于 2022年1月1日 17:39:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/70548037.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定