天天看點

go語言實作tcp并發伺服器與用戶端

go語言實作tcp并發伺服器端與用戶端

server.go

// nc 連接配接, 發送字母, 加收到轉大寫的字母
// 如果發送exit ,則會斷開連接配接
package main

import (
	"fmt"
	"net"
	"strings"
)

// 使用者處理
func handleConn(conn net.Conn) {
	defer conn.Close()
	remoteAddr := conn.RemoteAddr()
	fmt.Println(remoteAddr, " connect success")
	// 接收資料
	buf := make([]byte, 1024)
	for {
		n, err := conn.Read(buf)
		if err != nil {
			fmt.Println("err:", err)
			return
		}
		// windows會發送\r\n
		if "exit" == string(buf[:n-2]) {
			fmt.Println(remoteAddr, " 已斷開")
			return
		}
		fmt.Printf("from %s data:%s\n", remoteAddr, string(buf[:n]))

		// 發送資料
		to := strings.ToUpper(string(buf[:n]))
		conn.Write([]byte(to))
	}

}
func main() {
	// 建立server
	fmt.Println("tcp server run...")
	listener, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println("err:", err)
		return
	}
	defer listener.Close()
	var num int
	for {

		// 這裡會阻塞,處理使用者連接配接
		conn, err2 := listener.Accept()
		if err2 != nil {
			fmt.Println("accept err:", err2)
		}
		fmt.Println(num)
		num++
		go handleConn(conn)

	}

}
           

client端

// tcp用戶端
package main

import (
	"fmt"
	"io"
	"net"
	"os"
)

func main() {
	client, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println("err:", err)
		return
	}

	defer client.Close()
	go func() {
		input := make([]byte, 1024)
		for {
			n, err := os.Stdin.Read(input)
			if err != nil {
				fmt.Println("input err:", err)
				continue
			}
			client.Write([]byte(input[:n]))

		}
	}()

	buf := make([]byte, 1024)
	for {
		n, err := client.Read(buf)
		if err != nil {
			if err == io.EOF {
				return
			}
			fmt.Println("read err:", err)
			continue

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

	}

}