udp广播通信
乐果 发表于 2019 年 02 月 18 日 标签:udp
udp广播通信
特点:
1.数据传输不用建立连接,所以不可靠(符合udp协议的特点);
2.数据的发送是面向整个子网的,任何一台在子网内的计算机都可以接收到相同的数据;
3.广播用于udp和原始IP,不能用于TCP;
4.本地广播信息是不会被路由器转发,当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。这也是为什么IP协议的设计者故意没有定义互联网范围的广播机制;
用途:
1.定位本地子网内的主机
前提是已知该主机位于本地子网,但是不知到他的单播地址。例如通过广播向所有子网内的主机的某端口发送数据报,如果主机有进程在该端口等待接收数据并回射数据,那么在recvfrom中会得到该主机的单播地址。
例如:手机通过wifi(ip)方式投影到局域网的电视机这个场景中,电视机不断的通过udp广播方式向同一个局域网中的其他设备告知自身的ip,比如手机收到了广播报文,这时手机上发现了电视机这个设备(手机知道了电视机的ip地址)然后再链接电视机进行投影。
2.减少分组流通
例如,多个客户主机与一个服务器主机通信的局域网中,广播的方式会尽量减少分组流通。
广播地址:
广播地址是专门用于同时向网络中所有工作站进行发送的一个地址。在使用TCP/IP 协议的网络中,主机号为全1的IP地址为广播地址。例如,对于 :192.168.199.0(掩码:255.255.255.0)网段,其广播地址为192.168.199.255 (255 即为2进制的11111111 ),当发出一个目的地址为192.168.199.255的分组时,它将被分发给该网段上的所有计算机。
1.直接广播地址
指Host部分全为1的广播地址。如:192.168.199.255。当某机器发出目的地址为直接广播(如:192.168.199.255)时,路由器通过查找路由表可以转发,直到该网段。
2.受限广播地址
也称本地广播地址,它不被路由发送,但会被送到相同物理网络段上的所有主机,IP地址的网络号和主机号 全为1就是地址255.255.255.255,当某机器发出目的地址为本地广播时,路由器不会转发该包。所以该包只能限制在本网段
golang实例测试:
package main
import (
"fmt"
"log"
"net"
"time"
)
func main() {
//
go server()
//
for {
//定时广播自己的ip地址
client()
time.Sleep(1 * time.Second)
}
}
func server() {
for {
udpaddr, err := net.ResolveUDPAddr("udp4", "0.0.0.0:3001")
chkError(err)
//监听端口
udpconn, err2 := net.ListenUDP("udp", udpaddr)
chkError(err2)
//udp没有对客户端连接的Accept函数
clientHandle(udpconn)
}
}
func client() {
/////////////////////////////////////////////////////////////
// 广播,上报自己的ip地址
raddr := net.UDPAddr{
IP: net.IPv4(255, 255, 255, 255),
Port: 3001,
}
udpconn, err2 := net.DialUDP("udp", nil, &raddr)
chkError(err2)
//写入数据
_, err3 := udpconn.Write([]byte(udpconn.LocalAddr().String() + "\r\n"))
chkError(err3)
defer udpconn.Close()
}
func clientHandle(conn *net.UDPConn) {
defer conn.Close()
buf := make([]byte, 256)
//读取数据
//注意这里返回三个参数
//第二个是udpaddr
//下面向客户端写入数据时会用到
_, _, err := conn.ReadFromUDP(buf)
if err != nil {
return
}
fmt.Println(string(buf) + "==========")
}
func chkError(err error) {
if err != nil {
log.Fatal(err)
}
}
乐果 发表于 2019 年 02 月 18 日 标签:udp