博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
net包之IPConn
阅读量:4582 次
发布时间:2019-06-09

本文共 2715 字,大约阅读时间需要 9 分钟。

TCP和UDP并不是建立在IP层之上唯一的协议。该网站:http://www.iana.org/assignments/protocol-numbers 列表上大约有140关于它们(该列表往往在Unix系统的/etc/protocols文件上。)。TCP和UDP在这个名单上分别为6和17。

Go允许你建立所谓的原始套接字,使您可以使用这些其它协议通信,或甚至建立你自己的。但它提供了最低限度的支持: 它会连接主机, 写入和读取和主机之间的数据包。在接下来的章节中,我们将着眼于设计和实现自己的基于TCP之上的协议; 这部分认为同样的问题存在于IP层。

为了简单起见,我们将使用几乎最简单的例子: 如何发送一个ping消息给主机。Ping使用"echo"命令的ICMP协议。这是一个面向字节协议, 客户端发送一个字节流到另一个主机, 并等待主机的答复。格式如下:

  • 首字节是8, 表示echo消息
  • 第二个字节是0
  • 第三和第四字节是整个消息的校验和
  • 第五和第六字节是一个任意标识
  • 第七和第八字节是一个任意的序列号
  • 该数据包的其余部分是用户数据

下面的程序将准备一个IP连接,发送一个ping请求到主机,并得到答复。您可能需要root权限才能运行成功。

/* Ping */package mainimport (        "bytes"        "fmt"        "io"        "net"        "os")func main() {        if len(os.Args) != 2 {                fmt.Println("Usage: ", os.Args[0], "host")                os.Exit(1)        }        addr, err := net.ResolveIPAddr("ip", os.Args[1])        if err != nil {                fmt.Println("Resolution error", err.Error())                os.Exit(1)        }        conn, err := net.DialIP("ip4:icmp", addr, addr)        checkError(err)        var msg [512]byte        msg[0] = 8  // echo msg[1] = 0  // code 0 msg[2] = 0  // checksum, fix later msg[3] = 0  // checksum, fix later msg[4] = 0  // identifier[0] msg[5] = 13 //identifier[1] msg[6] = 0  // sequence[0] msg[7] = 37 // sequence[1] len := 8        check := checkSum(msg[0:len])        msg[2] = byte(check >> 8)        msg[3] = byte(check & 255)        _, err = conn.Write(msg[0:len])        checkError(err)        _, err = conn.Read(msg[0:])        checkError(err)        fmt.Println("Got response")        if msg[5] == 13 {                fmt.Println("identifier matches")        }        if msg[7] == 37 {                fmt.Println("Sequence matches")        }        os.Exit(0)}func checkSum(msg []byte) uint16 {        sum := 0        // assume even for now for n := 1; n < len(msg)-1; n += 2 {                sum += int(msg[n])*256 + int(msg[n+1])        }        sum = (sum >> 16) + (sum & 0xffff)        sum += (sum >> 16)        var answer uint16 = uint16(^sum)        return answer}func checkError(err error) {        if err != nil {                fmt.Fprintf(os.Stderr, "Fatal error: %s", err.Error())                os.Exit(1)        }}func readFully(conn net.Conn) ([]byte, error) {        defer conn.Close()        result := bytes.NewBuffer(nil)        var buf [512]byte        for {                n, err := conn.Read(buf[0:])                result.Write(buf[0:n])                if err != nil {                        if err == io.EOF {                                break                        }                        return nil, err                }        }        return result.Bytes(), nil}

转载于:https://www.cnblogs.com/zhepama/archive/2013/04/18/3028501.html

你可能感兴趣的文章
Tesnsorflow命名空间与变量管理参数reuse
查看>>
apply、call、bind有什么区别?
查看>>
linq 实现group by 不使用group关键字 等同lambad表达式中的group join 查询一对多关系...
查看>>
IP地址及子网掩码计算
查看>>
akka actor中的基本概念(学习小结)
查看>>
Gao the Grid ZOJ 3647 数三角形
查看>>
周总结
查看>>
进程与线程的区别+进程&线程的通信方式
查看>>
【SQL Server CE2.0】打开加密的数据库(源代码)
查看>>
linux进程管理命令
查看>>
Anaconda环境搭建
查看>>
USACO 好题汇总
查看>>
信号量
查看>>
Java_I/O输入输出_实现当用户输入姓名和密码时,将每一个姓名和密码加在文件中,如果用户输入done,就结束程序。...
查看>>
matplotlib学习笔记
查看>>
PHP-SplDoublyLinkedList
查看>>
微信的audio无法自动播放的问题
查看>>
VISUAL STUDIO 2010 单元测试
查看>>
Day Ten
查看>>
iOS开发---分类和扩展(Categories和Extensions)
查看>>