首页 > 其他分享 >golang中通过原始socket实现tcp/udp的服务端和客户端示例

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

时间:2023-04-21 14:46:33浏览次数:37  
标签:udp socket err 示例 nil fmt Printf net conn

这些天稍微空点,总结下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)
	}
}

标签:udp,socket,err,示例,nil,fmt,Printf,net,conn
From: https://www.cnblogs.com/davis12/p/17340297.html

相关文章

  • golang 中常用的超时控制的方案示例
    在go中,我们很容易就可以实现超时控制,今天分享2种解决方案:1.select+time.After2.select+context其实两种方案中,我们都是通过channel来控制的,在方案1中,对于time.After,通过返回一个只读<-chanTime实现,而context中,则通过context.Done()实现,通过返回<-chans......
  • 网络编程-UDP通信程序
    网络编程-UDP通信程序InetAddressaddress=InetAddress.getByName("Dinesaw");System.out.println("主机名:"+address.getHostName());System.out.println("IP地址:"+address.getHostAddress());UDP发送数据Java中的UDP通信UDP协议是一种不可靠的网络协议,它在通信的......
  • Spring中Redis存取数据示例
    1.导入StringRedisTemplate类importorg.springframework.data.redis.core.StringRedisTemplate;2.自动装配@AutowiredprivateStringRedisTemplatestringRedisTemplate;3.存数据(设置5分钟过期)Stringtoken=UUID.randomUUID().toString();Stringkey=RedisPrefix......
  • C#基础 ref out 函数参数 不算重载的简单示例
     .NETFramework:4.7.2       IDE:VisualStudioCommunity2019        OS:Windows10x64    typesetting:Markdown codeusingSystem;namespaceConsoleApp{classProgram{staticvoidMain(string[]args){......
  • C#基础 out 函数参数为out int类型 简单示例
     .NETFramework:4.7.2       IDE:VisualStudioCommunity2019        OS:Windows10x64    typesetting:Markdown codeusingSystem;usingSystem.Linq;namespaceConsoleApp{classProgram{publicstaticvoidMyFun(int......
  • udp编程及udp常见问题处理
    前言UDP协议是UserDatagramProtocol的缩写,它是无连接,不可靠的网络协议。一般使用它进行实时性数据的传输,主要是因为它快,但因为它是不可靠的一种传输协议,所以不可避免的会出现丢包现象。本文就具体讨论导致UDP传输数据包丢失的原因以及一些基本的规避方法:路由器转发造成的数据......
  • C#中的分布式ID生成组件IDGen介绍并给出示例代码
    C#中的IDGen是一个C#实现的TwitterSnowflake算法的ID生成器,可以生成全局唯一的ID,支持高并发场景下的ID生成。在本篇文章中,我们将介绍IDGen的使用方法并提供相关的C#示例代码。IDGen的介绍IDGen是一款开源的分布式唯一ID生成器,支持多种ID生成算法,并且可以在高并发场景下快速生成......
  • QUIC协议 对比 TCP/UDP 协议
    QUIC协议是HTTP3引入的,所以需要了解HTTP的版本迭代。HTTP1.x队头阻塞:下个请求必须在前一个请求返回后才能发出,导致带宽无法被充分利用,后续请求被阻塞(HTTP1.1尝试使用流水线(Pipelining)技术,但先天FIFO(先进先出)机制导致当前请求的执行依赖于上一个请求执行的完成,容易引起队头阻......
  • C++ - UDP通信
    UDPUDP就比较简单了,步骤比tcp要少一些。连接过程图:  1).服务器1.初始化套接字库WORDwVersion;WSADATAwsaData;interr;​wVersion=MAKEWORD(1,1);2.创建套接字SOCKETsockSrv=socket(AF_INET,SOCK_DGRAM,0);3.绑定//SOCKADDR_INaddrSrv;省略了定......
  • 使用Fiddler抓取WebSockets协议包
    背景服务端通过SignalR用WebSockets通讯方式,与显示屏进行交互,除了显示屏软件上日志入口,也能通过抓包抓取对应报文。同时,可通过工具模拟与显示屏软件推送信息。那HTTP和WebSocket有什么区别呢?引用网友写的描述HTTP建立在TCP协议基础上而WebSocket通常建立在TCP上,也说明了为什......