有时需要指定网络通信时本地使用的IP地址和端口号。

在Go语言中可通过定义 Dialer 中LocalAddr 成员实现。

Dialer结构定义如下:

  1. // A Dialer contains options for connecting to an address.
  2. //
  3. // The zero value for each field is equivalent to dialing
  4. // without that option. Dialing with the zero value of Dialer
  5. // is therefore equivalent to just calling the Dial function.
  6. type Dialer struct {
  7. ...
  8. // LocalAddr is the local address to use when dialing an
  9. // address. The address must be of a compatible type for the
  10. // network being dialed.
  11. // If nil, a local address is automatically chosen.
  12. LocalAddr Addr
  13. }

Addr是接口类型,其定义如下:

  1. // Addr represents a network end point address.
  2. //
  3. // The two methods Network and String conventionally return strings
  4. // that can be passed as the arguments to Dial, but the exact form
  5. // and meaning of the strings is up to the implementation.
  6. type Addr interface {
  7. Network() string // name of the network (for example, "tcp", "udp")
  8. String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80")
  9. }

目前实现Addr接口的类型并且被net 库支持的类型 包括:TCPAddr、UDPAddr、IPAddr。

下面通过代码演示如何指定client 使用的IP和端口号。

例子中使用TCPAddr 类型。

client


  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "net"
  6. "os"
  7. "time"
  8. )
  9. func DialCustom(network, address string, timeout time.Duration, localIP []byte, localPort int)(net.Conn,error) {
  10. netAddr := &net.TCPAddr{Port:localPort}
  11. if len(localIP) != 0 {
  12. netAddr.IP = localIP
  13. }
  14. fmt.Println("netAddr:", netAddr)
  15. d := net.Dialer{Timeout: timeout, LocalAddr: netAddr}
  16. return d.Dial(network, address)
  17. }
  18. func main() {
  19. serverAddr := "172.20.22.160:8080"
  20. // 172.28.0.180
  21. //localIP := []byte{0xAC, 0x1C, 0, 0xB4} // 指定IP
  22. localIP := []byte{} // any IP,不指定IP
  23. localPort := 9001 // 指定端口
  24. conn, err := DialCustom("tcp", serverAddr, time.Second*10, localIP,localPort)
  25. if err != nil {
  26. fmt.Println("dial failed:", err)
  27. os.Exit(1)
  28. }
  29. defer conn.Close()
  30. buffer := make([]byte, 512)
  31. reader := bufio.NewReader(conn)
  32. n, err2 := reader.Read(buffer)
  33. if err2 != nil {
  34. fmt.Println("Read failed:", err2)
  35. return
  36. }
  37. fmt.Println("count:", n, "msg:", string(buffer))
  38. select{}
  39. }

server

  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. "log"
  6. )
  7. func main() {
  8. addr := "0.0.0.0:8080"
  9. tcpAddr, err := net.ResolveTCPAddr("tcp",addr)
  10. if err != nil {
  11. log.Fatalf("net.ResovleTCPAddr fail:%s", addr)
  12. }
  13. listener, err := net.ListenTCP("tcp", tcpAddr)
  14. if err != nil {
  15. log.Fatalf("listen %s fail: %s", addr, err)
  16. } else {
  17. log.Println("rpc listening", addr)
  18. }
  19. for {
  20. conn, err := listener.Accept()
  21. if err != nil {
  22. log.Println("listener.Accept error:", err)
  23. continue
  24. }
  25. go handleConnection(conn)
  26. }
  27. }
  28. func handleConnection(conn net.Conn) {
  29. //defer conn.Close()
  30. var buffer []byte = []byte("You are welcome. I'm server.")
  31. n, err := conn.Write(buffer)
  32. if err != nil {
  33. fmt.Println("Write error:", err)
  34. }
  35. fmt.Println("send:", n)
  36. fmt.Println("connetion end")
  37. }

测试

启动client,只指定端口

  1. $ ./client
  2. netAddr: :9001
  3. count: 28 msg: You are welcome. I'm server.

启动client,指定IP,Port

  1. $ ./client
  2. netAddr: 172.28.172.180:9001
  3. count: 28 msg: You are welcome. I'm server

server输出

  1. ./sever
  2. 2018/06/19 18:15:41 rpc listening 0.0.0.0:8080
  3. send: 28
  4. connetion end

查看连接

  1. $ netstat -anp | grep 8080
  2. tcp 0 0 :::8080 :::* LISTEN 27328/./server
  3. tcp 0 0 ::ffff:172.20.22.160:8080 ::ffff:172.28.0.180:9001 ESTABLISHED 27328/./server

从测试结果看,可以成功指定IP和端口。

Golang client绑定本地IP和端口的更多相关文章

  1. socket的bind函数是不是只能绑定本地IP,不能绑定外网IP么?

    参考: https://bbs.csdn.net/topics/391024376 别瞎猜测. 所谓bind,就是指绑定本地接受端口. 指定ip,是为了分辨多ip主机. --------------- ...

  2. Docker容器绑定外部IP和端口

    Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务. 以下操作通过myfirstapp镜像模拟,如何制作myfirstapp镜像请点击此处. 1.外部访问容器容器启动之后,容器中可以 ...

  3. python - socket - client端指定ip和端口

    问题描述: 在设备中有3个NI, ip分别为192.168.1.5/6/7.其中本端192.168.1.6同对端192.168.1.10建立了一个tunnel. 我希望测试tunnel连通性, 对端起 ...

  4. 获取本地IP和端口号的指令

    ipconfig就可以获取ip 获取端口号的指令: 开始--运行--cmd--输入netstat an(中间有一空格)

  5. win10系统绑定本地IP和mac地址

    第一步:找到自己的IP和mac地址 1.按着win键+R键,输入cmd(大小写都一样) 2.命令: ipconfig   /all              #查看所有地址 然后按“回车键” 3.这样 ...

  6. iOS获取本地ip和端口

    #include <arpa/inet.h> #include <ifaddrs.h> #include <net/if.h> #define IOS_CELLUL ...

  7. establish状态,本地ip和端口连接本地ip端口可能是一样的。

    以下是从stackoverflow上抄下来的,很有帮助 How can you have a TCP connection back to the same port? A TCP connectio ...

  8. 华为核心交换机绑定IP+MAC+端口案例

    1         案例背景 某网络改造项目,核心交换机为华为S5700,接入交换机为不同型号交换机,如下模拟拓扑,客户端接入交换机1通过Access模式与核心交换机连接,该交换机下只有一个Vlan2 ...

  9. C# — 动态获取本地IP地址及可用端口

    1.在VS中动态获取本地IP地址,代码如下: 2.获取本机的可用端口以及已使用的端口:

随机推荐

  1. 关于“用VS2010的C++导入ADO导入不了,提示无法打开源文件msado15.tlh”的问题

    vc++2010中,要使用ado操作数据库,所以在stdafx.h中引入了ado的dll库,引入代码如下: #import "C:/Program Files/Common Files/Sy ...

  2. kbmMW安全第#3 - 基于硬件的随机数#2

    在之前的基于硬件的随机数博文中,我介绍了如何使用基于外部硬件的随机数生成器,来生成高质量的随机数. 但是,后来英特尔和AMD的CPU也包含随机值生成器.从2015年6月开始,来自Ivy Bridge的 ...

  3. Ubuntu 16.04安装vsftpd 并开启ftp服务

    1. 安装 sudo apt-get install vsftpd 2.可以使用下列命令来打开,关闭,重启ftp服务 sudo /etc/init.d/vsftpd start sudo /etc/i ...

  4. Android.mk使用第三方库方法

    /********************************************************************** * Android.mk使用第三方库方法 * 说明: * ...

  5. error:1407742 E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

    /********************************************************************************* * error:1407742 E ...

  6. paddle实践

    Docker image阅读:https://github.com/PaddlePaddle/book/blob/develop/README.cn.md docker run -d -p 8888: ...

  7. JAVA 第四章 数组

    数组保存的是一组有顺序的.具有相同类型的数据. 1.创建: 数组的声明格式: int arrary[]; int [] array1, array2; //同时声明多个数组. 上面的语句只是对数组进行 ...

  8. iphone上点击div会出现半透明灰色背景以及margin失效

    -webkit-tap-highlight-color         这个属性只用于iOS (iPhone和iPad).当你点击一个链接或者通过Javascript定义的可点击元素的时候,它就会出现 ...

  9. day python 010 函数(1)

    一 函数 定义 : def () 函数是对功能或者动作的封装 def yue (): # 形参列表 # print("拿出手机") # print("打开陌陌" ...

  10. The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online -C:Halting Problem(模拟)

    C Halting Problem In computability theory, the halting problem is the problem of determining, from a ...