Golang实现简单的Socket网络编程(代码+详细注释)

前言

用Go语言实现Socket网络编程

基于C/S开发模型

实现客户端与服务端之间的通信

客户端发送消息给服务端

服务端进行业务处理

服务端将处理好的数据返回给客户端

基础版

服务端只能同时服务一个客户端

只进行一次通话(收发消息)

客户端

客户端开发代码如下

package main

import (
	"fmt"
	"net"//Socket编程使用的包 需要引入
)

func main() {

	//与服务器建立连接
    //参数1表示使用TCP协议
    //参数2是"127.0.0.1:666"的省略写法
    //如果IP地址是本地回环IP 可以省略冒号之前的内容
	conn, err := net.Dial("tcp", ":666")
    
    //err == nil 时表示没有错误
	if err != nil {
		fmt.Println("net.Dial err:", err)
		return
	}

	fmt.Println("Dial success")

    //发送的数据是字符切片的格式
	sendData := []byte("hello")

	//向服务器发送数据
	cnt, err := conn.Write(sendData)

	if err != nil {
		fmt.Println("conn.Write err:", err)
		return
	}

	fmt.Println("Client to Server...")
	fmt.Println("length:", cnt, "data", string(sendData))

	//接收服务器返回的数据
	buf := make([]byte, 1024)

	cnt, err = conn.Read(buf)
	if err != nil {
		fmt.Println("conn.Read err:", err)
		return
	}

	fmt.Println("Server to Client...")
	fmt.Println("length:", cnt, "data", string(buf[:cnt])) //只处理前cnt个字符

	//关闭连接
	conn.Close()

}

服务端

服务端开发代码如下

package main

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

func main() {

	//创建监听
	ip := "127.0.0.1"
	port := 666

    //.Sprintf函数往address变量中写入IP和端口信息
	address := fmt.Sprintf("%s:%d", ip, port)

    //开始监听 选择TCP协议 和 监听的方向
	listener, err := net.Listen("tcp", address)

	if err != nil {
		fmt.Println("net.Listen err:", err)
		return
	}

	//提取连接
	conn, err := listener.Accept()
	if err != nil {
		fmt.Println("listener.Accept err:", err)
		return
	}

	fmt.Println("Accept success")

	//创建容器用于接收读取到的数据
	buf := make([]byte, 1024) //使用make函数创建切片

	//cnt是实际读到的字符数
	cnt, err := conn.Read(buf)
	if err != nil {
		fmt.Println("conn.Read err:", err)
		return
	}

	fmt.Println("Client to Server...")
	fmt.Println("length:", cnt, "data", string(buf))

	//服务器业务实现 小写转成大写
	upperData := strings.ToUpper(string(buf[:cnt])) //只处理前cnt个字符
	cnt, err = conn.Write([]byte(upperData))

	fmt.Println("Server to Client...")
	fmt.Println("length:", cnt, "data", upperData)

	//关闭连接
	conn.Close()

}

效果展示 

使用GoLand开发

效果截图如下

升级版

服务端可以同时服务多个客户端

并且每个客户端可以实现多次收发数据

核心思想

主GO程负责监听处理连接


子GO程负责处理数据 实现客户端与服务端互动的具体逻辑

客户端

客户端开发代码如下

package main

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

func main() {

	//与服务器建立连接
	conn, err := net.Dial("tcp", ":666")
	if err != nil {
		fmt.Println("net.Dial err:", err)
		return
	}

	fmt.Println("Dial success")
	//client0发送的内容是 "hello this is client 0"
	//client1发送的内容是 "hello this is client 1"
	sendData := []byte("hello this is client 0")

	//向服务器多次发送数据
	for {
		cnt, err := conn.Write(sendData)

		if err != nil {
			fmt.Println("conn.Write err:", err)
			return
		}

		fmt.Println("send data to server...")

		//接收服务器返回的数据
		buf := make([]byte, 1024)

		cnt, err = conn.Read(buf)
		if err != nil {
			fmt.Println("conn.Read err:", err)
			return
		}

		fmt.Println("Server to Client...")
		fmt.Println("length:", cnt, "data", string(buf[:cnt])) //只处理前cnt个字符

        //休息5秒再发送
		time.Sleep(5 * time.Second)
	}
}

服务端

服务端开发代码如下

package main

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

//业务处理函数需要接收conn参数 对应一个具体的客户端方向
func handle(conn net.Conn) {
	for {
		//创建容器用于接收读取到的数据
		buf := make([]byte, 1024) //使用make创建切片
		//cnt是实际读到的字符数
		cnt, err := conn.Read(buf)
		if err != nil {
			fmt.Println("conn.Read err:", err)
			return
		}

		fmt.Println("Client to Server...")
		fmt.Println("length:", cnt, "data", string(buf))

		//服务器业务 小写转成大写
		upperData := strings.ToUpper(string(buf[:cnt])) //只处理前cnt个字符
		cnt, err = conn.Write([]byte(upperData))

		fmt.Println("Server to Client...")
		fmt.Println("length:", cnt, "data", upperData)
	}
}

func main() {

	//创建监听
	ip := "127.0.0.1"
	port := 666
	address := fmt.Sprintf("%s:%d", ip, port)
	listener, err := net.Listen("tcp", address)

	if err != nil {
		fmt.Println("net.Listen err:", err)
		return
	}

	//主GO程负责监听处理连接
	//子GO程负责处理数据 实现客户端与服务端互动的具体逻辑

	//主GO程提取多个连接
	for {
		fmt.Println("listening...")
		conn, err := listener.Accept()

		if err != nil {
			fmt.Println("listener.Accept err:", err)
			return
		}

		fmt.Println("Accept success!")

		//启动一个子GO程 执行业务处理函数
		go handle(conn)
	}
}

效果展示 

使用GoLand开发

效果截图如下

补充

这是socket_client1.go的主函数

上文代码段是socket_client0.go的主函数

func main() {

   //与服务器建立连接
   conn, err := net.Dial("tcp", ":666")
   if err != nil {
      fmt.Println("net.Dial err:", err)
      return
   }

   fmt.Println("Dial success")
   //client0发送的内容是 "hello this is client 0"
   //client1发送的内容是 "hello this is client 1"
   sendData := []byte("hello this is client 1")

   //向服务器多次发送数据
   for {
      cnt, err := conn.Write(sendData)

      if err != nil {
         fmt.Println("conn.Write err:", err)
         return
      }

      fmt.Println("send data to server...")

      //接收服务器返回的数据
      buf := make([]byte, 1024)

      cnt, err = conn.Read(buf)
      if err != nil {
         fmt.Println("conn.Read err:", err)
         return
      }

      fmt.Println("Server to Client...")
      fmt.Println("length:", cnt, "data", string(buf[:cnt])) //只处理前cnt个字符

      time.Sleep(5 * time.Second)
   }
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Go语言(Golang)的网络编程是针对大规模后端服务程序设计的,网络通信在服务端程序中是不可或缺且至关重要的一部分。Go语言提供了两种主要的网络编程方式,即TCP socket编程和HTTP编程。 在TCP socket编程中,Go语言的net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket等。通过使用net包,可以方便地进行网络数据的传输和接收。在网络编程中,使用net.Listen函数可以返回一个在指定网络地址上监听的Listener,然后使用Accept函数等待客户端的连接请求,并创建一个新的goroutine来处理每个连接。同时,使用net.Conn接口可以进行数据的发送和接收。 下面是一个简单的示例代码,展示了如何使用Go语言进行TCP socket编程: ```go package main import ( "fmt" "net" ) func process(conn net.Conn) { defer conn.Close() for { buf := make([]byte,1024) n, err := conn.Read(buf) if err != nil { fmt.Println("读取数据错误:", err) return } fmt.Print(string(buf[:n])) } } func main() { fmt.Println("服务器开始监听...") listen, err := net.Listen("tcp", "0.0.0.0:8888") defer listen.Close() if err != nil { fmt.Println("监听错误:", err) return } for { fmt.Println("等待客户端连接...") conn, err := listen.Accept() if err != nil { fmt.Println("接受连接错误:", err) return } else { fmt.Printf("接受到客户端连接, 客户端地址:%v\n", conn.RemoteAddr()) go process(conn) } } } ``` 以上代码实现了一个简单的服务器程序,它监听本地地址的8888端口,并在接受到客户端连接后创建一个新的goroutine来处理连接。在处理连接的goroutine中,使用conn.Read函数从连接中读取数据,然后将读取到的数据打印出来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

没伞的男孩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值