Maison >développement back-end >Golang >Mise en réseau : votre premier serveur et client TCP/IP en Go

Mise en réseau : votre premier serveur et client TCP/IP en Go

Barbara Streisand
Barbara Streisandoriginal
2024-11-30 15:51:13261parcourir

Networking : Your First TCP/IP Server and Client in Go

? Ce que nous apprendrons

Dans ce didacticiel, nous démystifierons la programmation réseau en créant un serveur et un client TCP/IP simples mais robustes. Si vous vous êtes déjà demandé comment les applications communiquent sur un réseau, ce guide est fait pour vous !

? Conditions préalables

  • Connaissances de base en programmation Go
  • Curiosité pour le réseautage
  • Un éditeur de texte
  • Allez installé sur votre ordinateur
  • Module Go ajouté (utilisez go mod init tcpIp)

? Comprendre la communication réseau

Avant de plonger dans le code, décomposons ce qui se passe lorsque deux ordinateurs parlent :

  1. TCP/IP : Pensez-y comme à un appel téléphonique

    • TCP (Transmission Control Protocol) : garantit que les messages sont livrés dans leur intégralité et dans l'ordre
    • IP (Internet Protocol) : aide à acheminer les messages vers le bon appareil
  2. Rôles serveur et client :

    • Serveur : attend et écoute les connexions entrantes
    • Client : Initie le contact et envoie les demandes

?️ Structure du projet

tcp-chat-app/
├── server/
│   └── server.go   # Server-side logic
├── client/
│   └── client.go   # Client-side logic
└── main.go         # Starts both server and client

? Étape 1 : Création du serveur

Comprendre le code du serveur

package server

import (
    "log"
    "net"
)

// StartServer: Our digital receptionist 
func StartServer() {
    // Choose a "phone number" (address)
    address := "localhost:8080"

    // Set up a "phone line" to listen for calls
    listener, err := net.Listen("tcp", address)
    if err != nil {
        log.Fatalf("Couldn't set up the phone line: %v", err)
    }
    defer listener.Close()

    log.Printf("Server is ready, waiting for connections on %s", address)

    // Forever wait for incoming "calls"
    for {
        // Accept a new connection
        conn, err := listener.Accept()
        if err != nil {
            log.Printf("Missed a call: %v", err)
            continue
        }

        // Handle each "caller" in a separate conversation
        go handleClient(conn)
    }
}

Concepts clés expliqués

  • net.Listen() : Crée un « socket » réseau pour recevoir les connexions
  • Listener.Accept() : attend et accepte les connexions entrantes
  • go handleClient(conn) : gère chaque client dans un thread séparé (goroutine)

? Gestion des connexions client

func handleClient(conn net.Conn) {
    // Always clean up after the conversation
    defer conn.Close()

    log.Printf("New client connected: %s", conn.RemoteAddr())

    // Prepare a message buffer
    buffer := make([]byte, 1024)

    // Keep the conversation going
    for {
        // Read message from client
        n, err := conn.Read(buffer)
        if err != nil {
            log.Printf("Connection error: %v", err)
            return
        }

        // Echo the message back
        message := string(buffer[:n])
        log.Printf("Received: %s", message)
        conn.Write([]byte("Server says: " + message))
    }
}

Que se passe-t-il ici ?

  • buffer : Un stockage temporaire pour les messages entrants
  • conn.Read() : reçoit les messages du client
  • conn.Write() : renvoie des messages au client

?️ Étape 2 : Création du client

package client

import (
    "bufio"
    "fmt"
    "log"
    "net"
    "os"
)

func StartClient() {
    // Dial the server (like making a phone call)
    conn, err := net.Dial("tcp", "localhost:8080")
    if err != nil {
        log.Printf("Could not connect to server: %v", err)
        return
    }
    defer conn.Close()

    fmt.Println("Connected to server. Start chatting!")

    // Read user input and send to server
    scanner := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("> ")
        if !scanner.Scan() {
            break
        }

        message := scanner.Text()
        if message == "exit" {
            break
        }

        // Send message to server
        conn.Write([]byte(message + "\n"))

        // Wait for server's response
        response := make([]byte, 1024)
        n, err := conn.Read(response)
        if err != nil {
            log.Printf("Error receiving response: %v", err)
            break
        }

        fmt.Println(string(response[:n]))
    }
}

Mécanismes clients

  • net.Dial() : Connectez-vous au serveur
  • scanner.Scan() : Lire la saisie au clavier de l'utilisateur
  • conn.Write() : envoyer un message au serveur
  • conn.Read() : recevoir la réponse du serveur

? Rassembler tout cela : main.go

package main

import (
    "time"
    "tcpIp/server"
    "tcpIp/client"
)

func main() {
    // Start server in background
    go func() {
        server.StartServer()
    }()

    // Give server a moment to start
    time.Sleep(time.Second)

    // Launch client
    client.StartClient()
}

?‍♂️ Exécuter votre application réseau

go run main.go

? Ce que vous avez appris

  1. Concepts de base de la communication réseau
  2. Créer un serveur TCP dans Go
  3. Connexion d'un client au serveur
  4. Gérer les connexions réseau en toute sécurité
  5. Gestion des erreurs de base en programmation réseau

? Améliorations potentielles

  • Authentification
  • Support client multiple
  • Gestion robuste des erreurs
  • Cryptage

? Ressources

  • Documentation du package Go's net
  • Bases du protocole TCP/IP
  • Programmation simultanée en Go

Références

Administración.(2023, 9 août). Apprenez TCP/IP avec le guide gratuit de commutation et de routage pour tous. Cursin. https://cursin.net/en/learn-tcp-ip-with-the-free-switching-and-routing-guide-for-everyone/

Woodbeck, A. (2021). Programmation réseau avec Go. No Starch Press, Inc.

Bon réseautage ! ??

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn