当前位置:首页 » 云服务器 » javatcp如何判断服务器断开链接

javatcp如何判断服务器断开链接

发布时间: 2023-01-29 09:18:51

❶ tcp连接的断开

TCP的断开就是经过四次挥手: 这是正常的情况,客户端主动tcp连接断开的过程。客户端先是发送一个FIN为一的报文,然后进入FIN_WAIT_1的状态。 服务器收到FIN报文后,发送一个ACK报文,然后进入CLOSED_WAIT状态。 客户端收到服务器的ACK报文进入FIN_WAIT_2状态。 等到服务器觉得他数据处理好了,可以关闭的时候,会发送一个FIN报文,然后进入LAST_ACK。等待最后一个应答。 让客户端收到服务器FIN报文,就进入TIME_WAIT状态了,随后发送最后一个ACK报文,然后close。 客户端再等待2msl后也自己主动关闭。而只有主动关闭的情况下,才会有TIME_WAIT。 那么为什么四次挥手需要四次呢? 三次握手其实就是在第二次把ACK和SYN两个报文合并成一个发,但是断开的过程可能还有一方需要处理下数据,需要延长点时间,等处理好再发FIN,所以就比三次握手多了一次。 这里还有一个问题,为什么需要TIME_WAIT,然后到close需要2msl的时间呢? 先说下什么是MSL,也就是报文的最长生存时间,超过这个时间的报文就要被丢弃掉。tcp是基于ip的,ip上有个生存时间TTL,是ip报文可以经过的最大路由数量,每经过一个路由就减1,减到0,ip报文就丢弃掉,然后通过ICMP通知源主机,我们的ping也算是经过这个。当然msl和ttl还是有区别的,msl是时间,ttl是路由数量,msl也是大于等于ttl的。在linux中,2msl默认是60秒。 前文也说了,只有主动发起断开连接的进程才会有time wait状态。time wait+2msl有两个原因: 1.防止旧连接的数据包 像这个seq 301的包,如果因为网络的原因被延迟了,而没有time wait或者很短,那么连接断开后,又建立新的连接,这个时候这个包到了,可能就导致数据紊乱了。而2msl可以保证两个方向的包在断开前丢弃掉。 2.保证正确的断开连接 2msl的时间也是保证第四个报文的ack可以被被动关闭方接收到。 如图,假设time wait比较短或者没有,当最后的ack报文丢失的时候。客户端已经close了,而服务器一直处于last ack的状态。这样连接就不能正常断开了。而如果有time wait +2msl这个情况就可以避免。假设服务器没有收到最后一个ack报文,服务器会重发FIN等待客户端的ack。 这样就可以保证不会出现一端断开,另外一端没有断开的情况了。 有时候我们在服务器上会看到很多time wait。time wait一般就是服务器主动发起的断开请求才会产生的状态。所以time wait过多,第一个是系统资源会大量消耗,还有是端口如果占的太多,会导致没办法创建新连接。这个时候可以把linux的net.ipv4.tcp_tw_reuse开启,置为1,可以复用time wait超过1秒的连接。 这边再说说tcp的保活机制。也就是怎么长期维持客户端和服务端的连接。 在一个时间段内,如果没有连接等相关活动,tcp的保活机制会定期发探测报文,如果连续几个探测报文就没有回应,就将错误信息报告给系统,系统通知上层应用。 在 Linux 内核可以有对应的参数可以设置保活时间、保活探测的次数、保活探测的时间间隔,以下都为 默认值: tcp_keepalive_time=7200:表示保活时间是 7200 秒(2⼩时),也就 2 小时内如果没有任何连接 相关的活动,则会启动保活机制 tcp_keepalive_intvl=75:表示每次检测间隔 75 秒; tcp_keepalive_probes=9:表示检测 9 次无响应,认为对⽅方是不不可达的,从⽽而中断本次的连接。 也就是说在 Linux 系统中,最少需要经过 2 小时 11 分 15 秒才可以发现一个“死亡”连接。 当然这个时间也可以自己配置。

❷ 客户端怎么判断Socket连接已与服务器断开

法一:

当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

法二:

struct tcp_info info;
int len=sizeof(info);
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
if((info.tcpi_state==TCP_ESTABLISHED)) 则说明未断开 else 断开

法三:

若使用了select等系统函数,若远端断开,则select返回1,recv返回0则断开。其他注意事项同法一。

法四:

int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

设置后,若断开,则在使用该socket读写时立即失败,并返回ETIMEDOUT错误

法五:

自己实现一个心跳检测,一定时间内未收到自定义的心跳包则标记为已断开。

java网络编程中,对于客户端和服务器的tcp连接,如果客户端异常断开连接,服务器端如何获知,有什么方法

这个得用java心跳处理机制。就是客户端每隔一段时间向服务器发送指定信息,如果服务器没有收到客服端发来的信息,这时服务器和客服端连接就已经断开。具体的心跳实现网络上很多。

❹ TCP协议中客户端closescoket后,服务器怎么知道此用户已经断开

你可以根据服务器收到的数据的长度来判断,如果服务器收到的数据长度是0,那么意味着你的客户端程序已经断开了连接。从TCP/IP协议栈的角度来说,就是客户端程序关闭了自己写的这一半连接,向服务器发出了一个FIN。这涉及到TCP的状态迁移,关于这方面的知识,建议你看一下Richard
Stevens先生的《TCP/IP
详解》卷一和《Unix网络编程》卷一,上面有详细的解释。
关于你的第二个问题,建议你仔细看一下自己的服务器程序代码。服务器程序首先要建立一个监听socket,当有客户端连接上来时,服务器会在一个新socket上接受客户端连接。所以并不存在“乱”的问题。关于这个问题同样推荐你看上面的两本关于网络编程的经典着作。

❺ java socket怎么判断断开连接

一个方法sendUrgentData,查看文档后得知它会往输出流发送一个字节的数据,只要对方Socket的SO_OOBINLINE属性没有打开,就会自动舍弃这个字节,而SO_OOBINLINE属性默认情况下就是关闭的
下面一段代码就可以判断远端是否断开了连接:
try{
socket.sendUrgentData(0xFF);
}catch(Exception ex){
reconnect();
}

热点内容
掌握ftp服务器的配置与管理 发布:2024-05-03 08:06:58 浏览:766
服务器搭建的函数 发布:2024-05-03 07:54:44 浏览:815
php包含数组 发布:2024-05-03 07:53:51 浏览:702
短暂记忆存储信息是有限的 发布:2024-05-03 07:48:14 浏览:537
java集合对象 发布:2024-05-03 07:32:13 浏览:916
苹果自带脚本 发布:2024-05-03 07:16:04 浏览:569
商城导航源码 发布:2024-05-03 07:14:15 浏览:552
shell脚本日志输出 发布:2024-05-03 06:31:04 浏览:713
服务器快捷方式是什么意思 发布:2024-05-03 06:28:18 浏览:108
我的世界怎么成为服务器最靓的仔 发布:2024-05-03 06:26:44 浏览:853