Je fais des expériences avec Go - et je voudrais créer un serveur TCP auquel je peux me connecter en telnet, envoyer des commandes et recevoir des réponses.
const (
CONN_HOST = "localhost"
CONN_PORT = "3333"
CONN_TYPE = "tcp"
)
func main() {
listener, err := net.Listen(CONN_TYPE, fmt.Sprintf("%s:%s", CONN_HOST, CONN_PORT))
if err != nil {
log.Panicln(err)
}
defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
log.Panicln(err)
}
go handleRequest(conn)
}
}
func handleRequest(conn net.Conn) {
buffer := make([]byte, 1024)
length, err := conn.Read(buffer)
if err != nil {
log.Panicln(err)
}
str := string(buffer[:length])
fmt.Println(conn.RemoteAddr().String())
fmt.Printf("Received command %d\t:%s\n", length, str)
switch str {
case "PING\r\n":
sendResponse("PONG", conn)
case "PUSH\r\n":
sendResponse("GOT PUSH", conn)
default:
conn.Write([]byte(fmt.Sprintf("UNKNOWN_COMMAND: %s\n", str)))
}
conn.Close() // ferme la connexion
}
func sendResponse(res string, conn net.Conn) {
conn.Write([]byte(res+"\n"))
}
Le snippet ci-dessus fermera la connexion à chaque fois, me sortant de la session du terminal. Mais ce que je veux en réalité, c'est pouvoir garder la connexion ouverte pour plus d'opérations d'E/S. Si je supprime simplement conn.Close()
, alors le serveur semble être bloqué quelque part car il ne reçoit plus de réponses.
La manière dont j'ai résolu cela est d'avoir une boucle sans fin dans ma méthode handleRequest pour qu'elle ne se termine jamais tant qu'elle ne reçoit pas un message QUIT\r\n
. Est-ce approprié - ou y a-t-il une meilleure façon d'y parvenir ?
func handleRequest(conn net.Conn) {
for {
log.Println("Gestion de la demande")
buffer := make([]byte, 1024)
length, err := conn.Read(buffer)
if err != nil {
log.Panicln(err)
}
str := string(buffer[:length])
fmt.Println(conn.RemoteAddr().String())
fmt.Printf("Received command %d\t:%s\n", length, str)
switch str {
case "PING\r\n":
sendResponse("PONG", conn)
case "PUSH\r\n":
sendResponse("GOT PUSH", conn)
case "QUIT\r\n":
sendResponse("Au revoir", conn)
conn.Close()
default:
conn.Write([]byte(fmt.Sprintf("COMMANDE_INCONNUE : %s\n", str)))
}
}
}