网络编程【5】Golang创建TCP服务器和客户端

目录:
: TCP Server
	- 监听端口(获取链接请求)
	- 有链接请求创建套接字
	- 对套接字进行处理
: TCP Client
	- 创建socket套接字
	- 用户输入消息数据
	- 将消息写入套接字
	- 销毁socket
: 抓包分析
: 消息格式的重要性

一、TCP Server

func process(conn net.Conn) {
	defer conn.Close() // 不关闭的话,服务端会处于CLOSE—WAIT状态,最后被当做异常发送R包(Reset)
	for {
		var buf [128]byte
		n, err := conn.Read(buf[:])
		if err != nil {
			fmt.Println(err)
			break
		}
		conn.Write([]byte(fmt.Sprintf("received data: %s", string(buf[:n]))))
	}
	time.Sleep(time.Second * 5) // 睡眠一定时间,触发四次挥手包(为了抓包数据更好看)。否则关闭太快会把Ack包和Fin包并一起发送
}

func main() {
	// 1. 监听端口
	listen, err := net.Listen("tcp", "0.0.0.0:4000")
	if err != nil {
		log.Fatal(err)
	}
	defer listen.Close()
	for {
		socket, err := listen.Accept()  // 2. 接收请求返回套接字(阻塞)
		if err != nil {
			log.Fatal(err)
		}
		go process(socket)  // 3.处理请求
	}
}

二、TCP Client

func client() {
	// 1. 创建socket进行连接
	socket, err := net.Dial("tcp", "172.?.?.249:4000")
	if err != nil {
		log.Fatal("3000 ", err)
	}
	defer socket.Close()

	// 2.用户命令行输入消息
	userInput := bufio.NewReader(os.Stdin)
	for {
		// 3.一次数据以\n为止, 读到Q则关闭
		input, _:= userInput.ReadString('\n')
		if strings.TrimSpace(input) == "Q" {
			break
		}
		// 4.往socket写入数据
		if _, err := socket.Write([]byte(input)); err != nil {
			fmt.Println("3002", err)
		}
		// 5.接收返回数据
		var data [1024]byte
		n, err := socket.Read(data[:])
		if err != nil {
			fmt.Println("3003", err)
		}
		fmt.Println(string(data[:n]))
	}
}

func main() {
	client()
	fmt.Println("client close")
	time.Sleep(time.Second * 30)  // 若主进程关闭,其子进程不管有没释放连接都被强制关闭
}

三、抓包分析
TCP Server的 process函数的必须睡眠一定时间才能触发四次分手包,否则包太小,给网卡合并一起发出去了。
在这里插入图片描述
为甚么主动关闭方长时间处于FIN-WAIT2(服务端长时间为CLOSE-WAIT)?
若主动方离开FIN-WAIT2进入TIME-WAIT只需被动方发送FIN包。
所以被动方只发生了ACK包,没有发送FIN包(服务端没关闭连接)

四、消息格式的重要性
上面服务处理消息就是声明一个规格载体去接收数据,如果数据大于载体规格,就需要读两次以上。
所以当数据长度大于byte数组长度时,数据不完整,打印出来的数据也即不完整。
所有需要标明消息大小,以此知道接收多少字节才算完整的消息。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值