2899

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

0

文章评论