Go语言的Socket编程

作者: 帅气的昵称都有人用了 | 来源:发表于2019-04-11 17:10 被阅读5次

我们在日常开发当中,几乎所有网络编程都是Socket编程,因为大部分底层网络的编程都离不开Socket编程。


什么是Socket

其实Socket起源于UNIX,网络的Socket数据传输是一种特殊的I/OSocket也是一种文件描述符。
同文件的基本操作一样,Socket也有一个类似的函数--Socket(),该函数返回的是一个整型的Socket描述符,之后再进行类似于连接建立、数据传输等操作就都可以通过这个Socket来实现了。
我们知道,在计算机网络当中,存在着TCPUDP两种协议,因此Socket也相应的对应着两种类型:流式SocketSOCK_STREAM,和数据报式Socket(SOCK_DGRAM),其中流式Socket是一种面向连接的Socket,针对的是面向连接的TCP服务应用,数据报式Socket是一种无连接的Socket,针对的是面向无连接的UDP服务应用。
那么在建立一个Socket连接时,除了我们知道它是应用了哪种协议后,还有两个内容是需要确定的,就是IP地址和端口

Go语言所支持的IP类型

Go语言针对网络编程定义了net包,里面有很多关于网络编程的类型,函数和方法。其中IP的定义如下:

type IP []byte

虽然在net包中有很多的函数用于操作IP,但我们在这里只介绍几个比较常用的。
先来看第一个:ParseIP(s string),这个函数会把一个IPv4IPv6的地址转化为IP类型:

package main

import (
    "fmt"
    "net"
    "os"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Fprintf(os.Stderr, "Useage: %s IP Address\n", os.Args[0])
        os.Exit(1)
    }
    ipAddress := os.Args[1]
    addr := net.ParseIP(ipAddress)
    if addr == nil {
        fmt.Println("Invalid IP Address!")
    } else {
        fmt.Println("The IP Address is: ", addr.String())
    }
    os.Exit(0)
}

只要我们在执行时给定一个标准的IP地址,就会给出相应的IP格式


Dial()函数

在Go语言中,通常使用Dial()函数来连接服务器,Listen()进行监听,Accept()接收连接。
Go语言标准库对传统的Socket编程过程进行了抽象和封装,无论期望使用什么协议建立什么形式的连接,都只需要调用net.Dial()即可。
Dial()函数的原型如下:

func Dial(net, addr string) (Conn, error)

net参数是网络协议的名字,addr参数是IP地址或者域名,而端口号以:的形式跟随在地址或域名的后面,端口号可选。
几种常见协议的调用方式:
TCP

conn, err := net.Dial("tcp", "192.168.0.10:8888")

UDP

conn, err := net.Dial("udp", "192.168.0.10:8888")

ICMP

/** 使用协议名称 */
conn, err := net.Dial("ip4:icmp", "www.baidu.com")
/** 使用协议编号 */
conn, err := net.Dial("ip4:1", "10.0.0.1")

在连接建立成功之后,就可以进行数据的发送与接收了,其中发送使用的是Write()函数,接收使用的是Read()函数。

package main

import (
    "bytes"
    "fmt"
    "io"
    "net"
    "os"
)

func main() {
    if len(os.Args) != 2 {
        fmt.Println("Usage: ", os.Args[0], "hostname")
        os.Exit(1)
    }
    service := os.Args[1]
    conn, err := net.Dial("ip4:icmp", service)
    checkError(err)
    var msg [512]byte
    // ICMP报文
    msg[0] = 8  // echo
    msg[1] = 0  // code 0
    msg[2] = 0  // checksum
    msg[3] = 0  // checksum
    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("Get response...")
    if msg[5] == 13 {
        fmt.Println("Identifier match.")
    }
    if msg[7] == 37 {
        fmt.Println("Sequence match.")
    }
    os.Exit(0)
}
func checkError(err error) {
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %s", err.Error())
        os.Exit(1)
    }
}
func checkSum(msg []byte) uint16 {
    sum := 0
    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 readFully(conn net.Conn) ([]byte, error) {
    defer conn.Close()
    result := bytes.NewBuffer(nil)
    var buf [512]byte
    for {
        _, err := conn.Read(buf[0:])
        result.Write(buf[0:])
        if err != nil {
            if err == io.EOF {
                break
            }
            return nil, err
        }
    }
    return result.Bytes(), nil
}

运行程序后,如果取得响应,就会返回相应的结果,如下:

Get response...
Identifier match.
Sequence match.

相关文章

  • golang TCP Socket的一篇好文章

    Go语言TCP Socket编程

  • Go语言的Socket编程

    我们在日常开发当中,几乎所有网络编程都是Socket编程,因为大部分底层网络的编程都离不开Socket编程。 什么...

  • 打造一款属于自己的go语言socket框架

    前言: 一直对socket编程有很大的兴趣,经过一周多的努力与查阅资料终于打造一款属于自己的go语言socket框...

  • 转载记录,主要是自己学习

    以下文章全是转载 Go语言TCP Socket编程 递归返回值 js原型链 vue v-model java de...

  • Go语法指南

    出处---Go编程语言 欢迎来到 Go 编程语言指南。本指南涵盖了该语言的大部分重要特性 Go 语言的交互式简介,...

  • go Socket编程

    TCP Socket客户端 获取连接 串行指定读取客户端返回内容大小 按照指定方式循环读取 按行读取 io读取 S...

  • Go 语言学习技巧和编程思维

    Go 语言学习技巧和编程思维 一、了解 Go 语言 了解 Go 语言背景 学习 Go 语言,首先要了解 Go 语言...

  • Go语言入坑

    GO语言基础 认识并安装GO语言开发环境 Go语言简介 Go语言是谷歌2009年发布的第二款开源编程语言 go语言...

  • 48.Go语言书籍

    Go语言圣经(中文版) Go语言高级编程(Advanced Go Programming https://godo...

  • go语言有哪些优势?Go语言的核心特性有哪些

    Go语言,作为编程语言的后生,站在巨人的肩膀上,吸收了其他一些编程语言的特点。 Go 编程语言是一个开源项目,它使...

网友评论

    本文标题:Go语言的Socket编程

    本文链接:https://www.haomeiwen.com/subject/rbmgiqtx.html