一. 服务端接收数据并返回数据

  • 服务端代码 ```go package main

import ( “net” “fmt” )

func main() { //创建TCPAddress变量,指定协议tcp4,监听本机8899端口 addr, _ := net.ResolveTCPAddr(“tcp4”, “localhost:8899”)

//监听TCPAddress设定的地址 lis, _ := net.ListenTCP(“tcp4”, addr)

fmt.Println(“服务器已启动”)

//阻塞式等待客户端消息,返回连接对象,用于接收客户端消息或向客户端发送消息 conn, _ := lis.Accept()

//把数据读取到切片中 b := make([]byte, 256) fmt.Println(“read之前”) //客户端没有发送数据且客户端对象没有关闭,Read()将会阻塞,一旦接收到数据就不阻塞 count, _ := conn.Read(b) fmt.Println(“接收到的数据:”, string(b[:count]))

/ 向客户端发送数据 / conn.Write([]byte(“这是服务器传递的数据”))

//关闭连接 conn.Close() fmt.Println(“服务器结束”) }

  1. - 客户端代码
  2. ```go
  3. package main
  4. import (
  5. "net"
  6. "fmt"
  7. )
  8. func main() {
  9. //服务器端ip和端口
  10. addr, _ := net.ResolveTCPAddr("tcp4", "localhost:8899")
  11. //申请连接客户端
  12. conn, _ := net.DialTCP("tcp4", nil, addr)
  13. //向服务端发送数据
  14. count, _ := conn.Write([]byte("客户端传递的数据"))
  15. fmt.Println("客户端向服务端发送的数据量为:", count)
  16. /*
  17. 接收服务器传递回来的数据
  18. */
  19. b := make([]byte, 256)
  20. c, _ := conn.Read(b)
  21. fmt.Println(string(b[:c]))
  22. ////关闭连接
  23. conn.Close()
  24. fmt.Println("客户端结束")
  25. }
  • 可以在服务端添加循环,不停接收客户端发送来的数据,服务端代码修改如下 ```go package main

import ( “net” “fmt” )

func main() { addr, := net.ResolveTCPAddr(“tcp4”, “localhost:8899”) lis, := net.ListenTCP(“tcp4”, addr) fmt.Println(“服务器已启动”)

/ 服务器端添加死循环,不停的接收客户端对象 / for { conn, := lis.Accept() b := make([]byte, 256) count, := conn.Read(b) nc := string(b[:count]) fmt.Println(“接收到的数据:”, nc) conn.Write([]byte(“服务器:” + nc)) conn.Close() } fmt.Println(“服务器结束”) }

  1. - 客户端代码修改如下
  2. ```go
  3. package main
  4. import (
  5. "net"
  6. "fmt"
  7. "strconv"
  8. )
  9. func main() {
  10. //服务器端ip和端口
  11. addr, _ := net.ResolveTCPAddr("tcp4", "localhost:8899")
  12. //通过循环,模拟发送五次客户端请求
  13. for i := 1; i <= 5; i++ {
  14. conn, _ := net.DialTCP("tcp4", nil, addr)
  15. conn.Write([]byte("客户端数据" + strconv.Itoa(i)))
  16. b := make([]byte, 256)
  17. c, _ := conn.Read(b)
  18. fmt.Println("第", i, "次服务器返回的数据:", string(b[:c]))
  19. conn.Close()
  20. }
  21. fmt.Println("客户端结束")
  22. }

三.并发访问

  • 上面代码的问题是服务器获取到客户端对象后,如果客户端什么也没有输入,其他客户端无法连接.可以通过结合goroutine完成并发访问
  • 只需要修改server.go,在里面添加goroutine ```go package main

import ( “net” “fmt” )

func main() { addr, := net.ResolveTCPAddr(“tcp4”, “localhost:8899”) lis, := net.ListenTCP(“tcp4”, addr) fmt.Println(“服务器已启动”)

/ 服务器端添加死循环,不停的接收客户端对象 / for { conn, := lis.Accept() go func() { //在此处添加创建go func()即可 b := make([]byte, 256) count, := conn.Read(b) nc := string(b[:count]) fmt.Println(“接收到的数据:”, nc) conn.Write([]byte(“服务器:” + nc)) conn.Close() }() } fmt.Println(“服务器结束”) } ```