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和端口。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
使用Minio Golang客户端可以帮助您在Go应用程序中使用Minio对象存储服务。以下是使用Minio Golang客户端的步骤: 1. 安装Minio Golang客户端包 ```go go get github.com/minio/minio-go/v7 ``` 2. 初始化Minio Golang客户端 ```go package main import ( "context" "fmt" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" ) func main() { // 初始化Minio客户端对象 minioClient, err := minio.New("play.min.io", &minio.Options{ Creds: credentials.NewStaticV4("Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", ""), Secure: true, }) if err != nil { fmt.Println(err) return } // 使用minioClient操作对象存储服务 ... } ``` 3. 创建一个存储桶 ```go // 创建一个名为"test-bucket"的存储桶 err = minioClient.MakeBucket(context.Background(), "test-bucket", minio.MakeBucketOptions{}) if err != nil { fmt.Println(err) return } ``` 4. 上传文件到存储桶 ```go // 上传名为"test-object"的文件到存储桶 _, err = minioClient.FPutObject(context.Background(), "test-bucket", "test-object", "testfile.txt", minio.PutObjectOptions{}) if err != nil { fmt.Println(err) return } ``` 5. 下载存储桶中的文件 ```go // 下载名为"test-object"的文件到本地文件system err = minioClient.FGetObject(context.Background(), "test-bucket", "test-object", "/path/to/destination", minio.GetObjectOptions{}) if err != nil { fmt.Println(err) return } ``` 6. 列出存储桶中的所有对象 ```go objectsCh := make(chan minio.ObjectInfo) // 列出名为"test-bucket"的存储桶中的所有对象 go func() { defer close(objectsCh) for object := range minioClient.ListObjects(context.Background(), "test-bucket", minio.ListObjectsOptions{ Recursive: true, }) { if object.Err != nil { fmt.Println(object.Err) return } objectsCh <- object } }() for object := range objectsCh { fmt.Println(object.Key) } ``` 以上是使用Minio Golang客户端的基本步骤,您可以根据自己的实际需求进行调整。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值