做家常便饭网站,wordpress 亲子模板下载,花店网页模板html,网站和网页不同吗1. TCP连接超时简介
TCP是面向连接的协议#xff0c;通过三次握手建立连接#xff0c;但是#xff0c;在建立连接的过程中对方有可能没有响应#xff0c;这时候发起连接的一方会重试#xff0c;如果重试多次仍然没有响应#xff0c;就会触发超时#xff0c;从而导致连接…1. TCP连接超时简介
TCP是面向连接的协议通过三次握手建立连接但是在建立连接的过程中对方有可能没有响应这时候发起连接的一方会重试如果重试多次仍然没有响应就会触发超时从而导致连接失败socket的connect方法支持通过参数设置连接超时时间默认情况下也可以使用缺省的超时时间那么问题来了
连接的默认超时时间是多少如果超时时间设置为0会怎么样如果超时时间设置的非常大比如5分钟套接字会一直尝试连接吗
要回答这些问题还不太容易官方文档也没有给出下面咱们就自己尝试下寻找问题的答案。
2.TCP连接超时示例
本示例通过TCP套接字尝试连接一个不存在的IP地址所以肯定会连接失败示例中共尝试了5次第一次使用默认的超时时间第二次使用0超时时间第三次使用3秒超时时间第四次使用30秒超时时间第五次使用300秒超时时间每次连接前后都记录下当时的时间从而方便分析实际耗费的时间。本示例运行后的截图如下所示 下面详细介绍创建该应用的步骤。
步骤1创建Empty Ability项目。
步骤2在module.json5配置文件加上对权限的声明 requestPermissions: [ { name: ohos.permission.INTERNET }, { name: ohos.permission.GET_WIFI_INFO } ] 这里分别添加了访问互联网和访问WIFI信息的权限。
步骤3在Index.ets文件里添加如下的代码
import socket from ohos.net.socket; import wifiManager from ohos.wifiManager; import systemDateTime from ohos.systemDateTime;
//说明本地的IP地址不是必须知道的绑定时绑定到IP0.0.0.0即可显示本地IP地址的目的是方便对方发送信息过来 //本地IP的数值形式 let ipNum wifiManager.getIpInfo().ipAddress //本地IP的字符串形式 let localIp (ipNum 24) . (ipNum 16 0xFF) . (ipNum 8 0xFF) . (ipNum 0xFF);
Entry Component struct Index { //连接、通讯历史记录 State msgHistory: string //服务端IP地址 State serverIp: string 0.0.0.0 //服务端端口 State serverPort: number 9999 scroller: Scroller new Scroller() build() { Row() { Column() { Text(TCP连接超时演示) .fontSize(14) .fontWeight(FontWeight.Bold) .width(100%) .textAlign(TextAlign.Center) .padding(10) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(本地IP) .width(100) .fontSize(14) .flexGrow(0) Text(localIp) .width(110) .fontSize(12) .flexGrow(0) }.width(100%) .padding(5) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(服务端地址) .fontSize(14) .width(90) .flexGrow(0) TextInput({ text: this.serverIp }) .onChange((value) { this.serverIp value }) .width(110) .fontSize(12) .flexGrow(1) Text(:) .width(5) .flexGrow(0) TextInput({ text: this.serverPort.toString() }) .type(InputType.Number) .onChange((value) { this.serverPort parseInt(value) }) .fontSize(12) .flexGrow(0) .width(60) } .width(100%) .padding(5) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(默认超时时间) .fontSize(14) .width(130) .flexGrow(0) Text(default) .width(110) .fontSize(12) .flexGrow(1) Button(连接测试) .onClick(() { this.connect2Server(true, 0) }) .width(110) .fontSize(14) .flexGrow(0) } .width(100%) .padding(5) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(超时时间为0) .fontSize(14) .width(130) .flexGrow(0) Text(0) .width(110) .fontSize(12) .flexGrow(1) Button(连接测试) .onClick(() { this.connect2Server(false, 0) }) .width(110) .fontSize(14) .flexGrow(0) } .width(100%) .padding(5) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(超时时间为3秒) .fontSize(14) .width(130) .flexGrow(0) Text(3000) .width(110) .fontSize(12) .flexGrow(1) Button(连接测试) .onClick(() { this.connect2Server(false, 3000) }) .width(110) .fontSize(14) .flexGrow(0) } .width(100%) .padding(5) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(超时时间为30秒) .fontSize(14) .width(130) .flexGrow(0) Text(30000) .width(110) .fontSize(12) .flexGrow(1) Button(连接测试) .onClick(() { this.connect2Server(false, 30000) }) .width(110) .fontSize(14) .flexGrow(0) } .width(100%) .padding(5) Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { Text(超时时间为300秒) .fontSize(14) .width(130) .flexGrow(0) Text(300000) .width(110) .fontSize(12) .flexGrow(1) Button(连接测试) .onClick(() { this.connect2Server(false, 300000) }) .width(110) .fontSize(14) .flexGrow(0) } .width(100%) .padding(5) Scroll(this.scroller) { Text(this.msgHistory) .textAlign(TextAlign.Start) .padding(5) .width(100%) .backgroundColor(0xeeeeee) } .align(Alignment.Top) .backgroundColor(0xeeeeee) .height(300) .flexGrow(1) .scrollable(ScrollDirection.Vertical) .scrollBar(BarState.On) .scrollBarWidth(20) } .width(100%) .justifyContent(FlexAlign.Start) .height(100%) .padding(5) } .height(100%) } //连接服务端 async connect2Server(defaultTimeout: boolean, timeout: number) { //执行TCP通讯的对象 let tcpSocket socket.constructTCPSocketInstance(); let localAddress { address: 0.0.0.0, family: 1 } await tcpSocket.bind(localAddress) //服务端地址 let serverAddress { address: this.serverIp, port: this.serverPort, family: 1 } let option: socket.TCPConnectOptions { address: serverAddress } if (!defaultTimeout) { option { address: serverAddress, timeout: timeout } this.msgHistory 连接超时时间设置 timeout.toString() \r\n; } else { this.msgHistory 连接超时时间设置default \r\n; } this.msgHistory 连接开始时间 await getCurrentTimeString() \r\n; await tcpSocket.connect(option) .then(() { this.msgHistory connect success \r\n; }) .catch(async (e) { this.msgHistory connect fail e.message \r\n; this.msgHistory 连接结束时间 await getCurrentTimeString() \r\n\r\n; }) await tcpSocket.close() } }
//同步获取当前时间的字符串形式 async function getCurrentTimeString() { let time await systemDateTime.getDate().then( (date) { time date.getHours().toString() : date.getMinutes().toString() : date.getSeconds().toString() : date.getMilliseconds().toString() } ) return [ time ] }
步骤4编译运行可以使用模拟器或者真机。
步骤5配置服务端IP和端口一定要设置不存在的地址然后逐次单击“连接测试”按钮执行后的截图如下所示 截图的最后是连接日志信息 3.TCP连接超时分析
从输出的日志可以分析如下
1.默认的超时时间为5秒钟
2.超时时间设置为0时按照5秒钟计算超时时间
3.设置3秒钟或者30秒钟实际超时时间就是3秒钟或者30秒钟
4.设置大于65秒的超时时间实际超时时间为65秒左右
前3个好理解最后这个65秒是怎么回事呢这里分析一下实际上TCP连接重试时执行等待时间翻倍的规则也就是连接失败后等待1秒钟重试再失败等待2秒钟然后依次是4秒钟、8秒钟、16秒钟、32秒钟linux默认重试5次也就是1248163263秒钟再加上其他耗费的时间所以表现出来最大超时时间是65秒左右。
怎么样是不是对鸿蒙系统下TCP连接超时时间有了更清晰的认识呢
本文作者原创除非明确授权禁止转载
本文码云源码地址https://gitee.com/zl3624/harmonyos_network_samples/tree/master/code/tcp/TCPTimeoutDemo
本系列码云源码地址
https://gitee.com/zl3624/harmonyos_network_samples