拨号器的控制功能的目的是什么?

huangapple go评论85阅读模式
英文:

What is the purpose of dialer's control function?

问题

我目前正在学习使用Go进行网络编程。

目前,我正在进行一个使用上下文截止时间进行超时测试的项目。

package socket

import (
	"context"
	"net"
	"syscall"
	"testing"
	"time"
)

func TestDialContext(t *testing.T) {
	deadline := time.Now().Add(time.Second * 5)
	ctx, cancelFunc := context.WithDeadline(context.Background(), deadline)
	defer cancelFunc()

	var dialer net.Dialer
	dialer.Control = func(_, _ string, _ syscall.RawConn) error {
		time.Sleep(4 * time.Second)
		return nil
	}
	conn, err := dialer.DialContext(ctx, "tcp", "10.0.0.0:http")
	if err == nil {
		conn.Close()
		t.Fatal("expected no connection")
	}
	if nErr, ok := err.(net.Error); ok && nErr.Timeout() {
		t.Logf("expected timeout error: %v", err)
	} else {
		t.Errorf("expected timeout error; actual: %v", err)
	}
	if ctx.Err() != context.DeadlineExceeded {
		t.Errorf("expected deadline exceeded; actual: %v", ctx.Err())
	}
}

从代码中可以看出,我尝试使用一个带有5秒截止时间的上下文进行连接。

此外,通过使用dialer的控制函数,在请求时立即调用控制函数(实际上是在连接之前),以便在4秒后返回一个空错误。

按照我的意图,这个测试应该失败。原因是在5秒截止时间之前,控制函数返回了一个空错误。

但是测试结果如下所示。

=== RUN   TestDialContext
    dial_context_test.go:27: expected timeout error: dial tcp 10.0.0.0:80: i/o timeout
--- PASS: TestDialContext (5.01s)
PASS

控制函数的目的是什么?控制函数返回的错误与net.Dial()函数返回的错误无关吗?像我写的代码中使用控制函数的测试是否没有意义?

感谢阅读这个冗长的问题!

英文:

I am currently studying network programming in Go.

Currently, a timeout test using the deadline of the context is in progress by myself.

package socket

import (
	"context"
	"net"
	"syscall"
	"testing"
	"time"
)

func TestDialContext(t *testing.T) {
	deadline := time.Now().Add(time.Second * 5)
	ctx, cancelFunc := context.WithDeadline(context.Background(), deadline)
	defer cancelFunc()

	var dialer net.Dialer
	dialer.Control = func(_, _ string, _ syscall.RawConn) error {
		time.Sleep(4 * time.Second)
		return nil
	}
	conn, err := dialer.DialContext(ctx, "tcp", "10.0.0.0:http")
	if err == nil {
		conn.Close()
		t.Fatal("expected no connection")
	}
	if nErr, ok := err.(net.Error); ok && nErr.Timeout() {
		t.Logf("expected timeout error: %v", err)
	} else {
		t.Errorf("expected timeout error; actual: %v", err)
	}
	if ctx.Err() != context.DeadlineExceeded {
		t.Errorf("expected deadline exceeded; actual: %v", ctx.Err())
	}
}

As you can see from the code, I tried to connect using a context with a 5-second deadline.

In addition, by using the dialer's control function when requested, the control function is called immediately after being connected (actually right before being connected), so that a nil error is returned after 4 seconds.

By my intent, this test should fail. The reason is that the control function returns a nil error before the deadline of 5 seconds is reached.

But the test succeeds as below.

=== RUN   TestDialContext
    dial_context_test.go:27: expected timeout error: dial tcp 10.0.0.0:80: i/o timeout
--- PASS: TestDialContext (5.01s)
PASS

What exactly is the purpose of the control function? Is the error returned by the control function unrelated to the error returned by the net.Dial() function? Is the test using the control function like the code I wrote meaningless?

Thanks for reading this long question!

答案1

得分: 0

控制函数的目的是什么?

控制函数的目的是在创建套接字并建立连接之前,给拨号码一个机会来调用套接字底层文件描述符上的函数,例如 syscall.Setsockopt 函数之一。

控制函数返回的错误与 net.Dial() 函数返回的错误无关吗?

如果控制函数返回一个错误,那么拨号将以该错误失败。如果控制函数返回一个空错误,那么拨号将继续进行。

像我写的代码一样使用控制函数的测试是没有意义的吗?

基本上是的。你的控制函数会睡眠4秒,但除此之外没有做任何事情。

英文:

> What exactly is the purpose of the control function?

To give the dialing code a chance to call functions on the socket's underlying file descriptor — e.g. one of the syscall.Setsockopt functions — after the socket is created and before the connection is established.

> Is the error returned by the control function unrelated to the error returned by the net.Dial() function?

If the control function returns an error, then dialing fails with that error. If the control function returns a nil error, then dialing continues as usual.

> Is the test using the control function like the code I wrote meaningless?

Pretty much. Your control function sleeps 4 seconds but otherwise doesn't do anything.

huangapple
  • 本文由 发表于 2023年2月16日 07:35:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/75466420.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定