文档章节

go tcp 与 udp

solate
 solate
发布于 2016/11/25 17:34
字数 1844
阅读 103
收藏 0

TCP 与 UDP

TCP

TCP 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字 节流的一个端到端(Peer-to-Peer)的传输层协议.

如文件传送协议 FTP、网络终端协议 TELNET、SMTP、POP3、HTTP 协义等

获取本地的网络地址列表

这个获取的是本地如利用命令 ifconfig 看到的ip地址

可以去go获取本地ip地址这个博客看直接使用代码

func InterfaceAddrs() ([]Addr, error)

package main

import (
	"fmt"
	"net"
)

func main() {
	addr, err := net.InterfaceAddrs()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(addr)
}

获取主机所对应的IP

也就是获取远程url 对应主机对应在互联网中的ip地址

func LookupIP(host string) (addrs []IP, err error)

用来获取主机所对应的 IP 地址。IP 是一个[]byte 类型,用来表示一个 IP 地址,定义如

package main

import (
	"fmt"
	"net"
)

func main() {
	ips, err := net.LookupIP("www.baidu.com")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(ips)
}

建立TCPAddr

func ResolveTCPAddr(net, addr string) (*TCPAddr, os.Error)

该函数用来创建一个 TCPAddr,第一个参数为,tcp,tcp4 或者 tcp6,addr 是一个字符串,由 主机名或 IP 地址,以及":"后跟随着端口号组成.

例如: "127.0.0.1:8080",如果地址是一个 IPv6 地址,由于已经有冒号,主机部分,必须放在方括号 内, 例如:"[::1]:8080"。

package main

import (
	"fmt"
	"net"
)

func main() {
	ip, err := net.ResolveTCPAddr("tcp", "127.0.0.1:80")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(ip, ip.IP, ip.Port, ip.Network()) //127.0.0.1:80 127.0.0.1 80 tcp
}

服务端监听TCP连接

func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error)在指定的端口监听,等待客户端的链接

func (l *TCPListener) AcceptTCP() (*TCPConn, error) 用来接受客户端的请求,返回一个 Conn 链接,通过这个 Conn 来与客户端的进行通信。

func (l *TCPListener) Accept() (Conn, error) 底层实现是一样的

func (c *TCPConn) Write(b []byte) (int, error) 向 TCPConn 网络链接发送数据,b 是要发送的内容,返回值 int 为实际发送的字节数。

func (c *TCPConn) Read(b []byte) (int, error) 从 TCPConn 网络链接接收数据。返回值 Int 是实际接收的字节数。b 是接收的数据。

func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) 用来链接远程服务器。net 可以是 tcp、tcp4、tcp6 中的一个。Laddr 为本地地址,通常 传 null,raddr 是要链接的远端服务器的地址。成功返回 TCPConn,用返回的 TCPConn 可以 向服务器发送消息,读取服务器的响应信息。

//作为一个TCP的客户端,基本的操作流程如下:
service="www.google.com:80"
tcpAddr, err := net.ResolveTCPAddr("tcp4", service) //建立TCPAddr
conn, err := net.DialTCP("tcp", nil, tcpAddr) // 连接服务器
_, err = conn.Write([]byte("HEAD / HTTP/1.0\r\n\r\n"))  // 写信息
_, err = conn.Read(b) / result, err := ioutil.ReadAll(conn) //读取返回值


//服务器的基本操作流程为:
service:=":9090"
tcpAddr, err := net.ResolveTCPAddr("tcp4", service) //建立TCPAddr
l,err := net.ListenTCP("tcp",tcpAddr) //监听地址
conn,err := l.Accept() //接收消息
go Handler(conn) //此处使用go关键字新建线程处理连接,实现并发


注意:TCP 协议需要通信双方约定数据的传输格式,否则接收方无法判断数据是否 接收完成。

所以一般会自己去定义一个协议,比如定义[8]byte协议头,前4个byte放长度,后4个放状态。

如果发送端,发送数据后,调用 Close 关闭连接,不等待服务端的返回数据,服务端可 以用 ioutil.ReadAll 来读取数据,这时可以判断出 EOF,读取结束。 但如果客户端发送数据 后,没有关闭,而是等待服务端的数据返回,用 ReadAll 是不行的。 这里可以设置接收客户端超时,如果接收的消息超时需要有所处理

示例
//服务端





TCP 协议需要通信双方约定数据的传输格式,否则接收方无法判断数据是否 接收完成。在上面的例子中,SendData 用来发送数据,在数据发送前,添加结束标记, buf = append(buf, 0),用来表示数据发送结束。接收方收到 0 说明数据接收完成。 要么接收无法判断数据是否接收完。 如果发送端,发送数据后,调用 Close 关闭连接,不等待服务端的返回数据,服务端可 以用 ioutil.ReadAll 来读取数据,这时可以判断出 EOF,读取结束。但如果客户端发送数据 后,没有关闭,而是等待服务端的数据返回,用 ReadAll 是不行的。所以在上面的例子中, 用 0 来示数据的发送完成。

UDP

UDP 是用户数据报协议(User Datagram Protocol,UDP)的简称,UDP 协议提供的是 面向无连接的、不可靠的数据报投递服务。当使用 UDP 协议传输信息流时,用户应用程序 必须负责解决数据报丢失、重复、排序,差错确认等问题。 因为 UDP 不是面向链接的,所 以资源消耗小,处理速度快,通常音频、视频和普通数据在传送时使 UDP 较多。如 QQ 使 用的就是 UDP 协议。UDP 适用于一次只传少量数据的环境,数据报的最大长度根据操作环境的不同而各异。

从理论上说,包含报头在内的数据报的最大长度为 65535 字节。不过,一 些实际应用往往会限制数据报的大小,有时会降低到 8192 字节。

建立UDPAddr

func ResolveUDPAddr(net, addr string) (*UDPAddr, error) 把 addr 地址字符串,解析成 UDPAddr 地址。net 可以是”udp”,”udp4”,”udp6”,addr 是一 个地址字符串,由主机名或 IP 地址,以及“:”后面跟着的端口号组成。如果是 IPv6,主机 部分必须在方括内,如[::1]8080

服务端监听UDP连接

func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) 在指定的地址(laddr)监听,等待 UDP 数据包的到达。返回*UDPConn,可以使用连接的 ReadFrom 函数来读取 UDP 数据,用 WriteTo 来向客户端发送数据。

func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) 服务端用来读取 UDP 数据。Addr 是发送方的地址。

func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) 向 addr 发数据时用。b 是要发送的数据,addr 是接收方的地址。

func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) 连接到远端服务器 raddr,net 参数必须是”udp”,”udp4”,”udp6”中的一个。Laddr 通常为 nil,如果不是 nil 将使用 laddr 来连接到服务端。

func (c *UDPConn) Write(b []byte) (int, error) 用来向服务端发送数据。

func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) 与 ReadFrom 相同,用来读取发来 UDP 数据。

示例


在前面 TCP 的示例里,我们有约定,一条消息的结束标记。在 UDP 里,不需要有约定 结束标记,但需要约定,UDP 报文的最大长度。UDP 的数据,必须一次接收完成。比如上 面的例子中,我们用,var buf [1024]byte,定义了 1KB 的缓冲区来接收数据。因为我们发送 的数据量不大,所以可以一次读取。如果我们把上面的缓冲区改两个字节 var buf [2]byte 会 怎么样?大家可以自己试一下,会报一个错误: WSARecvFrom udp 0.0.0.0:7070: More data is available. 所以,UDP 通信的双方需要约定报文的最大长度。

示例等下补充。。。。。。。。

参考

一起学go.pdf

PS: 觉得不错的请点个赞吧!! (ง •̀_•́)ง

© 著作权归作者所有

共有 人打赏支持
solate
粉丝 7
博文 118
码字总数 97927
作品 0
成都
程序员
私信 提问
常用服务所对应端口号

echo 7/tcp echo 7/udp discard 9/tcp sink null discard 9/udp sink null systat 11/tcp users #Active users systat 11/udp users #Active users daytime 13/tcp daytime 13/udp qotd 17/t......

straymouse
2017/03/14
0
0
网络编程懒人入门(四):快速理解TCP和UDP的差异

原作者:MeloDev,本文由即时通讯网重新修订发布,感谢原作者的无私分享。 1、前言 对于即时通讯开者新手来说,在开始着手编写IM或消息推送系统的代码前,最头疼的问题莫过于到底该选TCP还是...

JackJiang2011
2017/10/27
0
0
Linux 占用端口查看

1、使用netstat -tunlp查看全部端口 [root@develop bin]# netstat -tunlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Prog......

04zhujunjie
2015/12/28
56
0
群晖NAS的各种端口

设置工具 类型 端口号码 协议 Synology Assistant 9999、9998、9997 UDP 备份 类型 端口号码 协议 Data Replicator、Data Replicator II、Data Replicator III 9999、9998、9997、137、138、...

poseyezi
2016/03/24
0
0
Udp、Tcp、Http Socket

1.TCP与UDP 面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会...

V_joy
2016/07/26
45
0

没有更多内容

加载失败,请刷新页面

加载更多

MaxCompute,基于Serverless的高可用大数据服务

摘要:2019年1月18日,由阿里巴巴MaxCompute开发者社区和阿里云栖社区联合主办的“阿里云栖开发者沙龙大数据技术专场”走近北京联合大学,本次技术沙龙上,阿里巴巴高级技术专家吴永明为大家...

zhaowei121
28分钟前
4
0
记录一下安装使用MySql8.0以及允许Navicat11远程连接

记录一下安装使用MySql8.0以及允许Navicat11远程连接 2018年05月11日 23:51:39 爱不离此 阅读数:4455 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_352...

linjin200
28分钟前
2
0
redis结合springboot 无法注入redisTemplate问题

redis结合springboot 无法注入redisTemplate问题 报错: Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.......

BraveLN
30分钟前
2
0
Redis缓存雪崩、缓存穿透、热点Key解决方案和分析

缓存穿透 缓存系统,按照KEY去查询VALUE,当KEY对应的VALUE一定不存在的时候并对KEY并发请求量很大的时候,就会对后端造成很大的压力。 (查询一个必然不存在的数据。比如文章表,查询一个不存...

watermelon11
31分钟前
2
0
ThinkSNS + 后端2019年1月更新播报

社交软件系统ThinkSNS+界面一览图 研发发布版本号:2.1.5 和 2.2.2 更新发布时间:2019年1月29日 社交系统ThinkSNS+后端本次主要更新内容:搜索地区体验优化、优化收藏页面排版、修正读取兑换...

ThinkSNS官方帐号
31分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部