Try to handle tcp fragmentation

This commit is contained in:
bdnugget 2025-01-15 10:51:43 +01:00
parent a48fef0186
commit 23474c19dc

59
main.go
View File

@ -1,7 +1,10 @@
package main package main
import ( import (
"bufio"
"encoding/binary"
"fmt" "fmt"
"io"
"log" "log"
"net" "net"
"sync" "sync"
@ -76,22 +79,29 @@ func handleConnection(conn net.Conn) {
PlayerId: int32(playerID), PlayerId: int32(playerID),
CurrentTick: 0, CurrentTick: 0,
} }
data, err := proto.Marshal(serverMsg) if err := writeMessage(conn, serverMsg); err != nil {
if err != nil {
log.Printf("Failed to marshal ServerMessage for player %d: %v", playerID, err)
return
}
if _, err := conn.Write(data); err != nil {
log.Printf("Failed to send player ID to player %d: %v", playerID, err) log.Printf("Failed to send player ID to player %d: %v", playerID, err)
return return
} }
// Listen for incoming actions from this player // Listen for incoming actions from this player
buf := make([]byte, 4096) reader := bufio.NewReader(conn)
for { for {
n, err := conn.Read(buf) // Read message length
if err != nil { lengthBuf := make([]byte, 4)
log.Printf("Error reading from player %d: %v", playerID, err) if _, err := io.ReadFull(reader, lengthBuf); err != nil {
log.Printf("Error reading message length from player %d: %v", playerID, err)
delete(players, playerID)
delete(playerConns, playerID)
delete(actionQueue, playerID)
return
}
messageLength := binary.BigEndian.Uint32(lengthBuf)
// Read message body
messageBuf := make([]byte, messageLength)
if _, err := io.ReadFull(reader, messageBuf); err != nil {
log.Printf("Error reading message from player %d: %v", playerID, err)
delete(players, playerID) delete(players, playerID)
delete(playerConns, playerID) delete(playerConns, playerID)
delete(actionQueue, playerID) delete(actionQueue, playerID)
@ -99,7 +109,7 @@ func handleConnection(conn net.Conn) {
} }
batch := &pb.ActionBatch{} batch := &pb.ActionBatch{}
if err := proto.Unmarshal(buf[:n], batch); err != nil { if err := proto.Unmarshal(messageBuf, batch); err != nil {
log.Printf("Failed to unmarshal action batch for player %d: %v", playerID, err) log.Printf("Failed to unmarshal action batch for player %d: %v", playerID, err)
continue continue
} }
@ -173,16 +183,29 @@ func processActions() {
state.ChatMessages = chatHistory[max(0, len(chatHistory)-5):] // Only send last 5 messages state.ChatMessages = chatHistory[max(0, len(chatHistory)-5):] // Only send last 5 messages
chatMutex.RUnlock() chatMutex.RUnlock()
data, err := proto.Marshal(state)
if err != nil {
log.Printf("Failed to marshal game state: %v", err)
return
}
// Send to each connected player // Send to each connected player
for _, conn := range playerConns { for _, conn := range playerConns {
if _, err := conn.Write(data); err != nil { if err := writeMessage(conn, state); err != nil {
log.Printf("Failed to send update: %v", err) log.Printf("Failed to send update: %v", err)
} }
} }
} }
// Helper function to write length-prefixed messages
func writeMessage(conn net.Conn, msg proto.Message) error {
data, err := proto.Marshal(msg)
if err != nil {
return err
}
// Write length prefix
lengthBuf := make([]byte, 4)
binary.BigEndian.PutUint32(lengthBuf, uint32(len(data)))
if _, err := conn.Write(lengthBuf); err != nil {
return err
}
// Write message body
_, err = conn.Write(data)
return err
}