Go语言实现TCP通信

这篇具有很好参考价值的文章主要介绍了Go语言实现TCP通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

TCP协议为传输控制协议,TCP协议有以下几个特点:
1. TCP是面向连接的传输层协议;
2. 每条TCP连接只能有两个端点,每条TCP连接是点到点的通信;
3. TCP提供可靠的交付服务,保证传送的数据无差错,不丢失,不重要且有序;
4. TCP提供全双工通信,允许双方在任何时候都能发送数据,为此TCP连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据;
5. TCP是面向字节流的;

发送缓存用来暂存以下数据:
① 发送应用程序传送给发送方TCP准备发送的数据;
② TCP已发送但尚未收到确认的数据;

接收缓存用来暂存以下数据:
① 按序到达但尚未被接收应用程序读取的数据;
② 不按序到达的数据;

因为是面向连接的协议,数据像水流一样传输,会存在黏包问题

TCP连接

一个TCP服务端可以同时连接很多个客户端,Go语言可以使用go关键字开启goroutine,每建立一个连接就创建一个goroutine,这样可以并发执行每一个创建的连接,tcp服务端主要的处理流程有:1. 监听端口;2. 接收客户端请求创建tcp连接;3. 使用go关键字开启goroutine处理每一个建立的连接,收发数据;4. 关闭连接;tcp客户端主要的处理流程有:1. 建立与服务端的连接;2. 收发数据;3. 关闭连接;关于tcp通信我们一般会使用到bufio,net,strings,os包,其中bufio包主要用来做输入输出数据的缓存,bufio.NewReader()函数可以传递os.Stdin类型(任何实现了io.Reader接口中的read()方法都可以作为参数传递进来,通常是传递一个实现了io.Reader接口中的read()方法的结构体或者是结构体指针),os.Stdin为标准输入,我们可以接受读取从控制台输入的数据,os.NewReader()函数返回的是一个新的带有4096 byte大小缓冲区的Reader结构体指针类型,通过Reader结构体指针类型我们就可以调用很多的方法,比如可以调用ReadString(delim byte) (string,error)方法,ReadString方法可以一直从标准输入中读取数据,直到遇到指定的终止符号delim,并且读取的内容会包含当前的delim,所以bufio包主要用来对输入和输出的数据进行缓冲;net包主要是连接的监听、创建,以及连接数据的读取和写入(例如tcp,udp等网络编程)等相关工作,tcp服务端中可以使用一个process()函数传递一个net.Conn类型也即*net.TCPConn类型的变量conn(TCPConn结构体实现了Conn接口),*TCPConn类型那么就可以调用很多的方法,因为我们需要从tcp连接中读取客户端或者是服务端发送的数据,所以可以调用*TCPConn类型的read()方法读取tcp连接的数据,然后输出数据即可,服务端可以使用net.Listen()函数监听连接,使用Accept()方法建立tcp连接,客户端则可以使用net.Dial()连接创建的tcp连接,使用conn接口的实现*TCPConn(Dial()方法的返回值就是*TCPConn类型)调用conn的read()方法将读取tcp连接的内容,write()方法将数据写入到tcp连接中;strings包主要是对读取到的数据的字符串形式进行处理,比如去除掉字符串的一些符号等等。

下面的代码需要先运行服务端的代码,再运行客户端的代码:文章来源地址https://www.toymoban.com/news/detail-421330.html

TCP服务端

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)

// TCP 服务端
func process(conn net.Conn) {
	// 函数执行完之后关闭连接
	defer conn.Close()
	// 输出主函数传递的conn可以发现属于*TCPConn类型, *TCPConn类型那么就可以调用*TCPConn相关类型的方法, 其中可以调用read()方法读取tcp连接中的数据
	fmt.Printf("服务端: %T\n", conn)
	for {
		var buf [128]byte
		// 将tcp连接读取到的数据读取到byte数组中, 返回读取到的byte的数目
		n, err := conn.Read(buf[:])
		if err != nil {
			// 从客户端读取数据的过程中发生错误
			fmt.Println("read from client failed, err:", err)
			break
		}
		recvStr := string(buf[:n])
		fmt.Println("服务端收到客户端发来的数据:", recvStr)
		// 由于是tcp连接所以双方都可以发送数据, 下面接收服务端发送的数据这样客户端也可以收到对应的数据
		inputReader := bufio.NewReader(os.Stdin)
		s, _ := inputReader.ReadString('\n')
		t := strings.Trim(s, "\r\n")
		// 向当前建立的tcp连接发送数据, 客户端就可以收到服务端发送的数据
		conn.Write([]byte(t))
	}
}

func main() {
	// 监听当前的tcp连接
	listen, err := net.Listen("tcp", "127.0.0.1:20000")
	fmt.Printf("服务端: %T=====\n", listen)
	if err != nil {
		fmt.Println("listen failed, err:", err)
		return
	}
	for {
		conn, err := listen.Accept() // 建立连接
		fmt.Println("当前建立了tcp连接")
		if err != nil {
			fmt.Println("accept failed, err:", err)
			continue
		}
		// 对于每一个建立的tcp连接使用go关键字开启一个goroutine处理
		go process(conn) 
	}
}

TCP客户端

package main

import (
	"bufio"
	"fmt"
	"net"
	"os"
	"strings"
)

func main() {
	// 连接到服务端建立的tcp连接
	conn, err := net.Dial("tcp", "127.0.0.1:20000")
	// 输出当前建Dial函数的返回值类型, 属于*net.TCPConn类型
	fmt.Printf("客户端: %T\n", conn)
	if err != nil {
		// 连接的时候出现错误
		fmt.Println("err :", err)
		return
	}
	// 当函数返回的时候关闭连接
	defer conn.Close() 
	// 获取一个标准输入的*Reader结构体指针类型的变量
	inputReader := bufio.NewReader(os.Stdin)
	for {
		// 调用*Reader结构体指针类型的读取方法
		input, _ := inputReader.ReadString('\n') // 读取用户输入
		// 去除掉\r \n符号
		inputInfo := strings.Trim(input, "\r\n")
		// 判断输入的是否是Q, 如果是Q则退出
		if strings.ToUpper(inputInfo) == "Q" { // 如果输入q就退出
			return
		}
		_, err = conn.Write([]byte(inputInfo)) // 发送数据
		if err != nil {
			return
		}
		buf := [512]byte{}
		// 读取服务端发送的数据
		n, err := conn.Read(buf[:])
		if err != nil {
			fmt.Println("recv failed, err:", err)
			return
		}
		fmt.Println("客户端接收服务端发送的数据: ", string(buf[:n]))
	}
}

到了这里,关于Go语言实现TCP通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python语言实现两台计算机用TCP协议跨局域网通信

    (这张图是在我本地电脑上用pycharm运行两个程序测试,实际可以在两台电脑上分别运行。) 实现的功能: 跨局域网通信(仅支持两台计算机) 跨局域网收发小文件,支持缓存在服务器,再一键接收(仅支持两台计算机) 在服务器上运行server.py程序,在两台客户机上分别运行

    2024年02月04日
    浏览(54)
  • 详解TCP/IP协议第三篇:通信数据在OSI通信模型的上下传输

    😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群:583783824   📚📚  工作微信:BigTreeJava 拉你进微信群,免费领取! 🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

    2024年02月09日
    浏览(44)
  • 【计算机网络】TCP传输控制协议——三次握手

    一开始,客户端和服务端都处于CLOSE状态,先是服务端监听某个端口,处于LISTEN状态。 然后客户端主动发起连接SYN,之后处于SYN-SEND状态。 服务端收到发起的连接,返回SYN,并且ACK客户端的SYN,之后处于SYN-RECV状态。 客户端收到服务端发送的SYN和ACK之后,发送ACK的ACK,之后处

    2024年02月09日
    浏览(49)
  • UDP(用户数据报协议)和TCP(传输控制协议)是互联网协议(IP)中两种主要的传输层协议

    您的描述是正确的。UDP(用户数据报协议)和TCP(传输控制协议)是互联网协议(IP)中两种主要的传输层协议。他们之间有几个重要的区别,其中之一就是建立连接的方式。 连接方式: • TCP:在进行数据传输之前,需要通过三次握手(3-way handshake)建立连接。这可以确保

    2024年02月02日
    浏览(116)
  • 【网络编程】TCP传输控制协议(Transmission Control Protocol)

    (꒪ꇴ꒪ ),Hello我是 祐言QAQ 我的博客主页:C/C++语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍 快上🚘,一起学习,让我们成为一个强大的攻城狮! 送给自己和读者的一句鸡汤🤔: 集中起来的意志可以击穿顽石! 作者水平很有限,如果发现错误,请在评论区指

    2024年02月09日
    浏览(43)
  • 通信模型四层(TCP/IP)、五层、七层(OSI)的作用、协议及数据传输单位

    四层模型 五层模型 七层模型 每层作用 物理层:传输比特流 数据链路层:控制网络层和物理层之间的通信 网络层:IP寻址和路由选择 传输层:建立、维护、管理端到端连接 会话层:建立、维护、管理会话连接 表示层:数据格式化,加密、解密、 应用层:为应用程序提供网

    2024年02月03日
    浏览(46)
  • TCP协议如何实现可靠传输

    TCP是面向连接的运输层协议,在无连接的、不可靠的IP网络服务基础之上提供可靠交付的服务。为此,在IP的数据报服务基础之上,增加了保证可靠性的一系列措施。 TCP最主要的特点: TCP是面向连接的输出层协议             每一条TCP连接只能有两个端点,每条TCP连接只能是

    2024年02月15日
    浏览(58)
  • java实现TCP协议文件传输

    客户端发数据到服务端 服务端 完整代码: 服务端 任务类 服务器类

    2024年02月12日
    浏览(53)
  • 【lwip】14-TCP协议分析之TCP协议之可靠传输的实现(TCP干货)

    ‍ 前面章节太长了,不得不分开。 这里已源码为主,默认读者已知晓概念或原理,概念或原理可以参考前面章节,有分析。 参考:李柱明博客:https://www.cnblogs.com/lizhuming/p/17438743.html ‍ lwip的时钟机制可以翻看前面章节。 lwip的TCP可靠传传输的实现离不开两个时钟处理函数:

    2024年02月06日
    浏览(58)
  • TCP协议是如何实现可靠传输的

    1.TCP 是面向连接的运输层协议,在无连接的、不可靠的 IP 网络服务基础之上提供可靠交付的服务。为此,在 IP 的数据报服务基础之上,增加了保证可靠性的一系列措施。 2.TCP最主要的特点 (1)TCP 是面向连接的运输层协议。         每一条 TCP 连接只能有两个端点 (endp

    2024年02月08日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包