时间:2020-3-11来源:本站原创作者:佚名
Dial函数的底层调用

在上篇教程中,我们介绍了Go语言中可以通过Dial()函数建立网络连接。实际上,Dial()函数是对dialTCP()、dialUDP()、dialIP()和dialUnix()的封装,这可以通过追溯Dial()函数的源码看到,底层真正建立连接是通过dialSingle()函数完成的:

dialSingle()函数通过从传入参数中获取网络协议类型调用对应的连接建立函数并返回连接对象。再往下追溯,可以看到这些底层函数最终都调用了syscall包的Socket()函数与对应平台操纵系统的SocketAPI交互实现网络连接的建立,针对不同的通信协议,建立不同的连接类型:

其中domain代表通信域,支持IPv4、IPv6和Unix,对应的常量值分别是syscall.AF_INET、syscall.AF_INET6和syscall.AF_UNIX。

注:IPv4和IPv6分别代表IP协议网络的第四版和第六版,Unix指的是类Unix操作系统中特有的通信域,在装有此类操作系统的同一台计算机中,应用程序可以基于此域建立socket连接。

typ代表Socket的类型,比如TCP对应的Socket类型常量是syscall.SOCK_STREAM(面向连接通信),UDP对应的Socket类型常量是syscall.SOCK_DGRAM(面向无连接通信),此外还支持syscall.SOCK_RAW和syscall.SOCK_SEQPACKET两种类型,SOCK_RAW其实就是原始的IP协议包,SOCK_SEQPACKET与SOCK_STREAM类似,都是面向连接的,只不过前者有消息边界,传输的是数据包,而不是字节流。通常,我们使用SOCK_STREAM和SOCK_DGRAM居多。

最后一个参数proto表示通信协议,一般默认为0,因为该值可以通过前两个参数判断得出,比如,前两个参数值分别为syscall.AF_INET和syscall.SOCK_DGRAM的时候,会选择UDP作为通信协议,前两个参数值分别为syscall.AF_INET6和syscall.SOCK_STREAM时,会选择TCP作为通信协议。

当然,我们在Go语言中编写网络程序时,完全不用关心这些底层的实现细节,只需要调用Dial函数并传入对应的参数就可以了。

网络超时处理

网络超时包含在多个环节中,比如连接超时、请求超时和响应超时,我们先来看连接超时。

1、连接超时

在使用Dial函数建立网络连接时,可以使用net包提供的DialTimeout函数主动传入额外的超时参数来建立连接,该函数原型如下:

funcDialTimeout(network,addressstring,timeouttime.Duration)(Conn,error){d:=Dialer{Timeout:timeout}returnd.Dial(network,address)}

和Dial函数调用一样,只是设置了超时字段而已,如果使用Dial函数,默认会通过操作系统提供的机制来处理连接超时,对于TCP连接,通常是3分钟左右,这对我们的程序来说,可能太长了,这个时候,就可以通过DialTimeout来建立连接,以上篇教程编写的示例代码tcp.go为例,如果请求国外被封的域名,比如facebook.







































白癫疯上海医院
北京最好的治疗白癜风的医院

转载请注明原文网址:http://www.gzdatangtv.com/jsyy/12819.html

------分隔线----------------------------