英文:
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'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'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("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")
}
}
}
'''
**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("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 {
}
}
'''
**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) > 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
}
'''
答案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)] < 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论