Go识别IPv6的服务

本文探讨了在Go语言中处理IPv6 Socket连接时遇到的问题,包括Socket连接超时导致的指纹识别失败,内外网连接超时设置的差异,以及Ping IPv6地址和Dial用法的示例。还提到了IPv6端口探活超时和IPv6指纹识别的特殊性,指出在并发、超时时间和IP格式上与IPv4的区别。
摘要由CSDN通过智能技术生成

IPv6 Socket连接

package main

import (
  "time"
  "fmt"
  "net"
  "regexp"
  "strconv"
  "encoding/hex"
)

func main() {

   addr := "[fe80::3de0:b557:a1f:d123%18]:80"
   timeout := 1
   taskSocket(addr,timeout)
}

// socket发送探测数据包编码
func DecodeData(s string) ([]byte, error) {
    sByteOrigin := []byte(s)
    matchRe := regexp.MustCompile(`\\(x[0-9a-fA-F]{
     2}|[0-7]{
     1,3}|[aftnrv])`)
    sByteDec := matchRe.ReplaceAllFunc(sByteOrigin, func(match []byte) (v []byte) {
        var replace []byte
        if isHexCode(match) {
            hexNum := match[2:]
            byteNum, _ := strconv.ParseInt(string(hexNum), 16, 32)
            replace = []byte{uint8(byteNum)}
        }
        if isStructCode(match) {
            structCodeMap := map[int][]byte{
                97:  []byte{
     0x07}, // \a
                102: []byte{
     0x0c}, // \f
                116: []byte{
     0x09}, // \t
                110: []byte{
     0x0a}, // \n
                114: []byte{
     0x0d}, // \r
                118: []byte{
     0x0b}, // \v
            }
            replace = structCodeMap[int(match[1])]
        }
        if isOctalCode(match) {
            octalNum := match[2:]
            byteNum, _ := strconv.ParseInt(string(octalNum), 8, 32)
            replace = []byte{uint8(byteNum)}
        }
        return replace
    })

    matchRe2 := regexp.MustCompile(`\\([^\\])`)
    sByteDec2 := matchRe2.ReplaceAllFunc(sByteDec, func(match []byte) (v []byte) {
        var replace []byte
        if isOtherEscapeCode(match) {
            replace = match
        } else {
            replace = match
        }
        return replace
    })
    return sByteDec2, nil
}

func isHexCode(b []byte) bool {
    matchRe := regexp.MustCompile(`\\x[0-9a-fA-F]{
     2}`)
    return matchRe.Match(b)
}

func isOctalCode(b []byte) bool {
    matchRe := regexp.MustCompile(`\\[0-7]{
     1,3}`)
    return matchRe.Match(b)
}

func isStructCode(b []byte) bool {
    matchRe := regexp.MustCompile(`\\[aftnrv]`)
    return matchRe.Match(b)
}

func isOtherEscapeCode(b []byte) bool {
    matchRe := regexp.MustCompile(`\\[^\\]`)
    return matchRe.Match(b)
}

func taskSocket(addr string,SocketTimeout int) {
   
   //1.连接端口
    connTimeout := time.Duration(int64(SocketTimeout))*time.Second // 设置socket连接超时时间
    //conn, errConn := net.DialTimeout("tcp", "[fe80::3de0:b557:a1f:d123%18]:80", connTimeout)
    /*
         tcp后面可以是IPv4的地址 也可以是IPv6的地址 ipv6的地址需要用中括号括起来[fe80::3de0:b557:a1f:d123%18]
         tcp4  只能传入ipv4地址
         tcp6  只能传入ipv6地址
    */  

    conn, errConn := net.DialTimeout("tcp6", addr, connTimeout)
    defer func(){
        if conn != nil{
            conn.Close()
        }
    }()

    if errConn != nil { // 连接端口失败
        fmt.Println(errConn)
    } else {
        fmt.Println("Socket连接端口成功")
    }

    //2.端口发送指纹数据
    conn.SetWriteDeadline(time.Now().Add(time.Second*time.Duration(int64(SocketTimeout))))
    hexNum :="474554202f20485454502f312e310d0a0d0a"
    

   data1, _ :=hex.DecodeString(hexNum) //数组形式
   datastr := string(data1)  //这里是乱码,导致响应的结果也是乱码
   fmt.Println(datastr)

    
    data_byte, err := DecodeData(datastr)
    if err != nil {
        fmt.Println(err)
    }
    _, errWrite := conn.Write(data_byte)

    if errWrite != nil {
        fmt.Println(errWrite)
    } else {
      fmt.Println("端口发送指纹数据成功")
    }


    //3.接收端口响应指纹数据
    var response []byte // 保存响应的结果
    conn.SetReadDeadline(time.Now().Add(time.Second*time.Duration(int64(SocketTimeout))))
    for true {
          buff := make([]byte, 4096)
        n, errRead := conn.Read(buff)
        if errRead != nil {
            if len(response) > 0 {
                break
            } else {
                fmt.Println(errRead)
            }
        }
        if n > 0 {
           response = append(response, buff[:n]...)
        }
    }


  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值