网络编程有两种:
1)TCP socket编程,是网络编程的主流。之所以叫tcp socket编程,是因为底层是基于tcp/ip协议的,比如QQ聊天。
2)b/s结构的http编程,我们使用浏览器去访问服务器时,使用的就是http协议,而http底层依旧是tcp socket实现的。

tcp编程

服务端的处理流程
1)监听端口
2)接收客户端的tcp链接,建立客户端和服务器端的链接
3)创建goroutine,处理该链接的请求(通常客户端会通过链接发送请求包)

客户端的处理流程
1)建立与服务端的链接
2)发送请求数据,接收服务器端返回的结果数据
3)关闭链接

server.go

  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. )
  6. func process(conn net.Conn) {
  7. //这里我们循环的接收客户端发送的数据
  8. defer conn.Close()
  9. for true {
  10. //创建一个新的切片
  11. buf := make([]byte, 1024)
  12. //1.等待客户端通过conn发送信息
  13. //2.如果客户端没有write[发送],那么协程就阻塞在这里
  14. fmt.Println("服务器在等待客户端发送信息", conn.RemoteAddr())
  15. n, err := conn.Read(buf) //从conn读取
  16. if err != nil {
  17. fmt.Println("客户端退出")
  18. return
  19. }
  20. //3.显示客户端发送的内容到服务器的终端
  21. fmt.Print(string(buf[:n]))
  22. }
  23. }
  24. func main() {
  25. fmt.Println("服务器开始监听。。。")
  26. //1.tcp表示使用网络协议是tcp
  27. //2. 0.0.0.0:8888表示在本地监听端口8888
  28. listen, err := net.Listen("tcp", "0.0.0.0:9999")
  29. if err != nil {
  30. fmt.Println("listen err=", err)
  31. return
  32. }
  33. defer listen.Close() //延时关闭listen
  34. //循环等待客户端来连接我
  35. for true {
  36. //等待客户端连接
  37. fmt.Println("等待客户端连接")
  38. conn, err := listen.Accept()
  39. if err != nil {
  40. fmt.Println("accept() err=", err)
  41. } else {
  42. fmt.Printf("accept() suc con=%v 客户端ip=%v\n", conn, conn.RemoteAddr())
  43. }
  44. //这里准备起一个协程,为客户端服务
  45. go process(conn)
  46. }
  47. fmt.Printf("listen suc=%v\n", listen)
  48. }

client.go

  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "net"
  6. "os"
  7. "strings"
  8. )
  9. func main() {
  10. conn, err := net.Dial("tcp", "127.0.0.1:9999")
  11. if err != nil {
  12. fmt.Println("client dail err=", err)
  13. return
  14. } else {
  15. fmt.Println("conn 成功=", conn)
  16. }
  17. for true {
  18. //功能一:客户端可以发送单行数据,然后就退出
  19. reader := bufio.NewReader(os.Stdin) //os.stdin 代表标准输入【终端】
  20. //从终端读取一行用户输入,并准备发送给服务器
  21. line, err := reader.ReadString('\n')
  22. if err != nil {
  23. fmt.Println("readstring err=", err)
  24. }
  25. line = strings.Trim(line, "\r\n")
  26. //fmt.Println(line[:len(line)-2])
  27. if line == "exit" {
  28. fmt.Println("退出")
  29. return
  30. }
  31. //再将line发送给服务器
  32. n, err := conn.Write([]byte(line))
  33. if err != nil {
  34. fmt.Println("conn.Write err=", err)
  35. }
  36. fmt.Printf("客户端发送了%d字节的数据\n", n)
  37. }
  38. }