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

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

Dialer结构定义如下:

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

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

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

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

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

例子中使用TCPAddr 类型。

client


package main import ( "bufio"
"fmt"
"net"
"os"
"time"
) func DialCustom(network, address string, timeout time.Duration, localIP []byte, localPort int)(net.Conn,error) {
netAddr := &net.TCPAddr{Port:localPort} if len(localIP) != 0 {
netAddr.IP = localIP
} fmt.Println("netAddr:", netAddr) d := net.Dialer{Timeout: timeout, LocalAddr: netAddr}
return d.Dial(network, address)
} func main() { serverAddr := "172.20.22.160:8080" // 172.28.0.180
//localIP := []byte{0xAC, 0x1C, 0, 0xB4} // 指定IP
localIP := []byte{} // any IP,不指定IP
localPort := 9001 // 指定端口
conn, err := DialCustom("tcp", serverAddr, time.Second*10, localIP,localPort)
if err != nil {
fmt.Println("dial failed:", err)
os.Exit(1)
}
defer conn.Close() buffer := make([]byte, 512)
reader := bufio.NewReader(conn) n, err2 := reader.Read(buffer)
if err2 != nil {
fmt.Println("Read failed:", err2)
return
} fmt.Println("count:", n, "msg:", string(buffer)) select{}
}

server

package main

import (
"fmt"
"net"
"log"
) func main() { addr := "0.0.0.0:8080" tcpAddr, err := net.ResolveTCPAddr("tcp",addr) if err != nil {
log.Fatalf("net.ResovleTCPAddr fail:%s", addr)
} listener, err := net.ListenTCP("tcp", tcpAddr)
if err != nil {
log.Fatalf("listen %s fail: %s", addr, err)
} else { log.Println("rpc listening", addr)
} for {
conn, err := listener.Accept()
if err != nil {
log.Println("listener.Accept error:", err)
continue
} go handleConnection(conn) } } func handleConnection(conn net.Conn) { //defer conn.Close() var buffer []byte = []byte("You are welcome. I'm server.") n, err := conn.Write(buffer) if err != nil { fmt.Println("Write error:", err)
}
fmt.Println("send:", n) fmt.Println("connetion end") }

测试

启动client,只指定端口

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

启动client,指定IP,Port

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

server输出

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

查看连接

$ netstat -anp | grep 8080
tcp 0 0 :::8080 :::* LISTEN 27328/./server
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. java学习笔记30(IO :缓冲流)

    缓冲流: 读取数据大量的文件时,读取的速度慢,java提供了一套缓冲流,提高IO流的效率: 缓冲流分为字节缓冲流和字符缓冲流: 字节输入缓冲流和字节输出缓冲流如下: package com.zs.De ...

  2. h5 手机端适配问题汇总

    1.uc手机浏览器竟然没有 sessionstorage 醉了 2.opera 浏览器  能识别 a标签中href的  javascript:; 为网址  ,  55555 3.safari 的弹框如 ...

  3. JAVA中将byte[]数组转成16进制字符串

    方法一: /** * byte数组转化为16进制字符串 * @param bytes * @return */ public static String byteToHexString(byte[] ...

  4. 河工大玲珑校赛重现の rqy的键盘

    题目传送门:http://218.28.220.249:50015/JudgeOnline/problem.php?id=1263 1263: rqy的键盘 时间限制: 1 秒  内存限制: 128 ...

  5. 通过javascript的日期对象来得到当前的日期,并输出--内置对象---JS

    //通过javascript的日期对象来得到当前的日期,并输出. var mydate = new Date(); var week = ["星期日","星期一" ...

  6. Redis过期策略(转)

    1.设置过期时间 expire key time(以秒为单位)--这是最常用的方式 setex(String key, int seconds, String value)--字符串独有的方式 具体的 ...

  7. [LeetCode&Python] Problem 860. Lemonade Change

    At a lemonade stand, each lemonade costs $5. Customers are standing in a queue to buy from you, and ...

  8. python------模块定义、导入、优化 ------time模块

    1.模块介绍 2.time & datetime 3.random 4.os 5.sys 6.shutil 7.json & pickle 8.shelve 9.xml处理 10.ya ...

  9. Go Example--常量

    package main import ( "fmt" "math" ) const s string = "constant" //定义字 ...

  10. vue全家桶+Koa2开发笔记(1)--vuex

    1.  安装webpack的问题: webpack坑系列--安装webpack-cli 2.  vue-cli(vue脚手架)超详细教程 3.  在命令行中使用 touch 执行新建文件: 4.  关 ...