go 语言之网络编程

网络编程基本介绍

golang 的主要设计目标之一就是面向大规模后端服务程序,网络通讯是服务必不可少的

网络编程有两种

1)TCP socket编程,是网络编程的主流,之所以叫TCP socket编程,是因为底层基于TCP/IP协议的,QQ聊天

2)b/s 结构的http编程,我们使用浏览器访问服务器时,使用的就是http协议,而http底层依旧是用TCP socket 实现的

TCP/IP

 

TCP 的全称是:
👉 Transmission Control Protocol

它属于:
👉 传输层

一句话理解:

TCP 是一种“可靠、有序、不丢数据”的网络通信协议
二、为什么需要 TCP?

你可以对比一下发送消息:

❌ 不可靠通信(类似 UDP)
发出去就不管了
可能丢
顺序可能乱
✅ TCP 做的事情:
数据不会丢(尽量保证)
顺序不会乱
对方一定收到(否则重发)

👉 本质:帮你兜底网络的不稳定
三、TCP 的核心特点(重点)
1️⃣ 面向连接(Connection-oriented)

通信前必须先建立连接:

👉 经典过程:
👉 三次握手

简单理解:

客户端:我能连你吗?
服务端:可以
客户端:那我开始发数据了
2️⃣ 可靠传输

TCP 通过这些机制保证可靠:

✅ 确认应答(ACK)
✅ 超时重传
✅ 校验和(防数据损坏)

👉 如果你做爬虫/接口请求,这一点非常关键

3️⃣ 有序传输

TCP 会给每个数据包编号:

👉 序列号

即使数据乱序到达,也能恢复顺序。

4️⃣ 流量控制

防止接收方被撑爆:

👉 滑动窗口

简单理解:

对方处理慢 → 我就少发一点

5️⃣ 拥塞控制(高级重点)

防止网络崩溃:

慢启动
拥塞避免
快重传

👉 类似:

网络堵车 → 自动降速

四、TCP 通信流程(完整)
1️⃣ 建立连接

👉 三次握手

2️⃣ 数据传输

👉 可靠、有序传输

3️⃣ 断开连接

👉 四次挥手
五、TCP vs UDP(一定要会)
特性	TCP	UDP
是否连接	✅ 有连接	❌ 无连接
是否可靠	✅	❌
速度	较慢	很快
应用	HTTP / 数据库	视频 / 游戏
六、现实中的 TCP 应用

你每天都在用:

浏览网页 → HTTP(基于 TCP)
数据库连接
SSH 远程登录
API 请求

👉 举例:
你访问网站:

浏览器 → TCP → 服务器 → 返回数据
七、用一句人话总结 TCP

TCP 就像“打电话”:
先接通 → 再说话 → 保证对方听到 → 挂断

  osi 与TCP/IP 协议参考模型(来自网络下图)

image

IP地址

概述: 每个internet 上的主机和路由器都有一个IP地址,它包括网络号和主机号,IP地址有IPv4(32位)或者ipv6(128位),centos系统ip a win系统通过ipconfig 查看

端口介绍

端口指特定TCP/IP或者UDP 协议中的端口,是逻辑意义上的端口

1)只要做服务程序,都必须监听一个端口

2)该电脑就是其他程序和该服务通讯的通道

3)一台电脑有65535个端口

入门

package net

import "net"

net包提供了可移植的网络I/O接口,包括TCP/IP、UDP、域名解析和Unix域socket。

虽然本包提供了对网络原语的访问,大部分使用者只需要Dial、Listen和Accept函数提供的基本接口;以及相关的Conn和Listener接口。crypto/tls包提供了相同的接口和类似的Dial和Listen函数。

Dial函数和服务端建立连接:

conn, err := net.Dial("tcp", "google.com:80")
if err != nil {
	// handle error
}
fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
status, err := bufio.NewReader(conn).ReadString('\n')
// ...
Listen函数创建的服务端:

ln, err := net.Listen("tcp", ":8080")
if err != nil {
	// handle error
}
for {
	conn, err := ln.Accept()
	if err != nil {
		// handle error
		continue
	}
	go handleConnection(conn)
}

  func Listen

func Listen(net, laddr string) (Listener, error)
返回在一个本地网络地址laddr上监听的Listener。网络类型参数net必须是面向流的网络:

"tcp"、"tcp4"、"tcp6"、"unix"或"unixpacket"。参见Dial函数获取laddr的语法。

  示例service

package main

import (
	"fmt"
	_"io"
	"net"
)
func main(){
	fmt.Println("开始监听了")
	//1.TCP表示使用的协议是TCP的
	//2.0.0.0.0:8888 表示本机所有地址的8888端口
	lisen, err :=net.Listen("tcp","0.0.0.0:8888")
	if err !=nil{
		fmt.Println("lisen err=",err)
		return
	}
	fmt.Printf("lisen=%v\n",lisen)
	defer lisen.Close() //延迟关闭监听
	for{
		fmt.Println("等待客户端连接")
		conn, err :=lisen.Accept() //等待客户端连接

		if err != nil{
			fmt.Println("监听失败")
		}else{
			fmt.Printf("Accept() suc con=%v 客户端IP=%v\n",conn,conn.RemoteAddr().String())
		}
		//这里启动协程响应客户端请求
		go func (con net.Conn)  {
		defer con.Close()//一定关闭
		for {
			//
			buy :=make([]byte,1024)
			//con.Read(buy) 等待客户端发生信息
			//如果客户端,没有发送数据,那么协程会阻塞这里
			fmt.Printf("服务器在等待客户端%s输入\n",con.RemoteAddr().String())
			n,err :=con.Read(buy)
			if  err !=nil{
				fmt.Println("客户端关闭")
				return
			}
			//显示客户端发送的内容到服务器终端
			fmt.Println(string(buy[:n]))
		}
		
	}(conn)
	}
	
}

//执行结果
// PS D:\golang\goproject\src\src01\go_code\src> go run chapter19\tcpdome01\server\main.go
// 开始监听了
// lisen=&{0xc000070a08 {<nil> 0 0}}
// 等待客户端连接
// Accept() suc con=&{{0xc000070c88}} 客户端IP=10.9.8.207:1597
// 等待客户端连接
// 服务器在等待客户端10.9.8.207:1597输入
// nihao

// 服务器在等待客户端10.9.8.207:1597输入
// 客户端关闭
// Accept() suc con=&{{0xc000070f08}} 客户端IP=10.9.8.207:6912
// 等待客户端连接
// 服务器在等待客户端10.9.8.207:6912输入
// utg

// 服务器在等待客户端10.9.8.207:6912输入
// 客户端关闭

  

  示例 客户端

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
)
func main(){
	conn,err := net.Dial("tcp","10.9.8.207:8888")
	if err != nil{
		fmt.Println("连接失败err=",err)
		return
	}
	fmt.Println("conn成功=",conn)
	//准备和客户端发生单行数据
	reader :=bufio.NewReader(os.Stdin)
	//从终端读取用户的输入,并发送到服务器断
	str,err :=reader.ReadString('\n')
	if err !=nil{
		fmt.Println("readString err",err)
	}
	//将str 发送给服务器
	n,err :=conn.Write([]byte(str))//将str 转成切片后发给服务器
	if err !=nil{
		fmt.Printf("发送信息失败err=\n",err)
	}
	fmt.Printf("客户端发生了=%v字节,并退出\n",n)
}



// PS D:\golang\goproject\src\src01\go_code\src> go  run chapter19\tcpdome01\client\main.go
// conn成功= &{{0xc000070a08}}
// nihao
// 客户端发生了=7字节,并退出
// PS D:\golang\goproject\src\src01\go_code\src> go  run chapter19\tcpdome01\client\main.go
// conn成功= &{{0xc000070a08}}
// utg
// 客户端发生了=5字节,并退出

  

 

posted @ 2026-03-30 10:58  烟雨楼台,行云流水  阅读(1)  评论(0)    收藏  举报