golang中通过原始socket实现tcp/udp的服务端和客户端示例

这些天稍微空点,总结下golang中通过tcp/udp实现服务端客户端的编程实现,毕竟长久以来,如果要截单的http服务,我们直接使用net/http包实现服务,或者使用框架如gin/echo/beego等。

以下就直接上代码,稍微看看都能懂起。

1.TCP的实现

server

package main

import (
	"bufio"
	"fmt"
	"net"
)

func main()  {
	// create lis
	lis, err := net.Listen("tcp", "0.0.0.0:8000")
	if err != nil {
		fmt.Printf("listen failed, err: %v\n", err)
		return
	}

	// loop, accept and handle
	for {
		conn, err := lis.Accept()
		if err != nil {
			fmt.Printf("accept failed, err: %v\n", err)
			continue
		}

		// handle conn with new goroutine
		go serve(conn)
	}
}

func serve(conn net.Conn)  {
	defer conn.Close()

	// handle
	for {
		// recv
		reader := bufio.NewReader(conn)
		var buf [1024]byte
		n, err := reader.Read(buf[:])
		if err != nil {
			fmt.Printf("read from conn failed, err: %v\n", err)
			break
		}
		recv := string(buf[:n])
		// handle
		fmt.Printf("recv data: %v\n", recv)

		// send
		_, err = conn.Write([]byte("OK"))
		if err != nil {
			fmt.Printf("send from conn failed, err: %v\n", err)
			break
		}
	}
}

client

package main

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

func main()  {
	// 1.create conn
	conn, err := net.Dial("tcp", "0.0.0.0:8000")
	if err != nil {
		fmt.Printf("conn server failed, err: %v\n", err)
		return
	}

	// 2.send and recv
	input := bufio.NewReader(os.Stdin)
	for {
		s, _ := input.ReadString('\n')
		s = strings.TrimSpace(s)
		if strings.ToUpper(s) == "Q" {
			return
		}

		_, err = conn.Write([]byte(s))
		if err != nil {
			fmt.Printf("send failed, err: %v\n", err)
			return
		}

		// recv date from server
		var buf [1024]byte
		n, err := conn.Read(buf[:])
		if err != nil {
			fmt.Printf("read failed: %v\n", err)
			return
		}
		fmt.Printf("recv from server ack: %v\n", string(buf[:n]))
	}

}

2.UDP的实现

server

package main

import (
	"fmt"
	"net"
)

func main()  {
	// create udp server
	lis, err := net.ListenUDP("udp", &net.UDPAddr{
		IP: net.IPv4(0, 0, 0, 0),
		Port: 8001,
	})
	if err != nil {
		fmt.Printf("listem failed, err: %v\n", err)
		return
	}

	defer lis.Close()

	for {
		var buf [1024]byte
		n, addr, err := lis.ReadFromUDP(buf[:])
		if err != nil {
			fmt.Printf("read data failed, err: %v\n", err)
			return
		}

		fmt.Printf("addr: %v\t, count: %v\t, data: %v\n", addr, n, string(buf[:n]))

		// send data
		_, err  = lis.WriteToUDP([]byte("ok"), addr)
		if err != nil {
			fmt.Printf("send data failed, err: %v\n", err)
			return
		}
	}
}

client

package main

import (
	"fmt"
	"net"
	"time"
)

func main()  {
	// create service
	lis, err := net.DialUDP("udp", nil, &net.UDPAddr{
		IP: net.IPv4(0, 0, 0, 0),
		Port: 8001,
	})

	if err != nil {
		fmt.Printf("lis udp server failed, err: %v\n", err)
		return
	}
	defer lis.Close()

	// send and recv
	for {
		// send
		sendData := []byte("hello, server")
		_, err = lis.Write(sendData)
		if err != nil {
			fmt.Printf("send data failed, err: %v\n", err)
			return
		}
		// recv
		buf := make([]byte, 4096)
		n, addr, err := lis.ReadFromUDP(buf)
		if err != nil {
			fmt.Printf("recv data failed, err: %v\n", err)
			return
		}

		fmt.Printf("recv data: %v, addr: %v, count: %v\n", string(buf[:n]), addr, n)
		time.Sleep(2 * time.Second)
	}
}

posted on 2023-04-21 14:37  进击的davis  阅读(452)  评论(0编辑  收藏  举报

导航