Golang client绑定本地IP和端口
有时需要指定网络通信时本地使用的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和端口的更多相关文章
- socket的bind函数是不是只能绑定本地IP,不能绑定外网IP么?
		
参考: https://bbs.csdn.net/topics/391024376 别瞎猜测. 所谓bind,就是指绑定本地接受端口. 指定ip,是为了分辨多ip主机. --------------- ...
 - Docker容器绑定外部IP和端口
		
Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务. 以下操作通过myfirstapp镜像模拟,如何制作myfirstapp镜像请点击此处. 1.外部访问容器容器启动之后,容器中可以 ...
 - python - socket - client端指定ip和端口
		
问题描述: 在设备中有3个NI, ip分别为192.168.1.5/6/7.其中本端192.168.1.6同对端192.168.1.10建立了一个tunnel. 我希望测试tunnel连通性, 对端起 ...
 - 获取本地IP和端口号的指令
		
ipconfig就可以获取ip 获取端口号的指令: 开始--运行--cmd--输入netstat an(中间有一空格)
 - win10系统绑定本地IP和mac地址
		
第一步:找到自己的IP和mac地址 1.按着win键+R键,输入cmd(大小写都一样) 2.命令: ipconfig /all #查看所有地址 然后按“回车键” 3.这样 ...
 - iOS获取本地ip和端口
		
#include <arpa/inet.h> #include <ifaddrs.h> #include <net/if.h> #define IOS_CELLUL ...
 - establish状态,本地ip和端口连接本地ip端口可能是一样的。
		
以下是从stackoverflow上抄下来的,很有帮助 How can you have a TCP connection back to the same port? A TCP connectio ...
 - 华为核心交换机绑定IP+MAC+端口案例
		
1 案例背景 某网络改造项目,核心交换机为华为S5700,接入交换机为不同型号交换机,如下模拟拓扑,客户端接入交换机1通过Access模式与核心交换机连接,该交换机下只有一个Vlan2 ...
 - C# — 动态获取本地IP地址及可用端口
		
1.在VS中动态获取本地IP地址,代码如下: 2.获取本机的可用端口以及已使用的端口:
 
随机推荐
- 终止TTask.Run启动的线程
			
unit Unit15; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, Syste ...
 - FCC JS基础算法题(6):Truncate a string(截断字符串)
			
先看一下题目描述: 如果字符串的长度比指定的参数num长,则把多余的部分用...来表示.切记,插入到字符串尾部的三个点号也会计入字符串的长度.但是,如果指定的参数num小于或等于3,则添加的三个点号不 ...
 - wsgi&nginx-理解
			
WSGI协议 首先弄清下面几个概念:WSGI:全称是Web Server Gateway Interface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述web ...
 - 基于区域的OSPF简单认证
			
实验要求:掌握OSPF区域简单认证配置 拓扑如下: 配置如下: R1enable configure terminal interface s0/0/0ip address 192.168.1.1 2 ...
 - websocket js 代码样例
			
function StartWebSocket(wsUri) { websocket = new WebSocket(wsUri); websocket.onopen = function(evt) ...
 - DG备库,实时应用如何判断,MR进程,及MRP应用归档,三种情况的查询及验证
			
本篇文档学习,DG备库,实时应用如何判断,MR进程,及MRP应用归档,三种情况的查询及验证 1.取消MRP进程 备库查询进程状态select process,client_process,sequen ...
 - 【特征提取】MultiBlock-LBP特征
			
MB-LBP特征,注意区分是Multi-block LBP还是MultiScale Block LBP,区别是是否使用了多尺度方法.其中Multiscale Block LBP,来源于论文,中科院的人 ...
 - windows 10 下sublime text 3配置c/c++编译环境
			
来源于在网上各种帖子,自己成功配置之后写作笔记: 检查环境变量 首先配置重定义环境变量,过程如下: 创建一个test.c文件 内容: #include <stdio.h> int main ...
 - java-Integer类
			
1.为什么会有基本类型包装类 * 将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据. 2.常用操作 * 常用的操作之一:用于基本数据类型与字符串之间的转换. * Intege ...
 - python笔记-1(import导入、time/datetime/random/os/sys模块)
			
python笔记-6(import导入.time/datetime/random/os/sys模块) 一.了解模块导入的基本知识 此部分此处不展开细说import导入,仅写几个点目前的认知即可.其 ...