Java 如何检查客户端是否已断开连接?
我有一个带套接字的java程序。我需要检查客户端是否已断开连接。我需要一个如何做到这一点的例子。我已经研究过了,但我不明白。因此,有人可以编写示例代码并解释所有内容 对不起,英语不好 我的代码:Java 如何检查客户端是否已断开连接?,java,Java,我有一个带套接字的java程序。我需要检查客户端是否已断开连接。我需要一个如何做到这一点的例子。我已经研究过了,但我不明白。因此,有人可以编写示例代码并解释所有内容 对不起,英语不好 我的代码: Stackoverflow上的相关线程以及解决方案。基本上,解决方案说检测客户机-服务器断开连接的最佳方法是尝试从套接字读取数据。如果读取成功,则连接处于活动状态。如果在读取过程中引发异常,则客户端和服务器之间没有连接。或者,可能会发生这样的情况:为套接字配置了一个超时值,以便读取操作完成。如果超过此超
Stackoverflow上的相关线程以及解决方案。基本上,解决方案说检测客户机-服务器断开连接的最佳方法是尝试从套接字读取数据。如果读取成功,则连接处于活动状态。如果在读取过程中引发异常,则客户端和服务器之间没有连接。或者,可能会发生这样的情况:为套接字配置了一个超时值,以便读取操作完成。如果超过此超时,将引发套接字超时异常,这可以被视为客户端已断开连接或网络已关闭
这篇文章还讨论了如何使用isReachable方法-reference。但是,此方法仅告诉我们是否可以访问远程主机。这可能只是客户端与服务器断开连接的原因之一。使用此技术将无法检测到由于客户端崩溃或终止而导致的断开连接。Stackoverflow上的相关线程以及解决方案。基本上,解决方案说检测客户机-服务器断开连接的最佳方法是尝试从套接字读取数据。如果读取成功,则连接处于活动状态。如果在读取过程中引发异常,则客户端和服务器之间没有连接。或者,可能会发生这样的情况:为套接字配置了一个超时值,以便读取操作完成。如果超过此超时,将引发套接字超时异常,这可以被视为客户端已断开连接或网络已关闭
这篇文章还讨论了如何使用isReachable方法-reference。但是,此方法仅告诉我们是否可以访问远程主机。这可能只是客户端与服务器断开连接的原因之一。使用此技术,您将无法检测到由于客户端崩溃或终止而导致的断开连接。如果客户端已正确断开连接: read将返回-1 readLine返回null 任何其他X抛出EOFEException的readXXX。
检测TCP连接丢失的唯一真正可靠的方法是对其进行写入。最终,这将抛出一个IOException:连接重置,但由于缓冲,至少需要两次写入。如果客户端已正确断开连接: read将返回-1 readLine返回null 任何其他X抛出EOFEException的readXXX。
检测TCP连接丢失的唯一真正可靠的方法是对其进行写入。最终,这将抛出一个IOException:连接重置,但由于缓冲,至少需要两次写入。您能否提供一些代码,以便我们提供帮助!我做了复制粘贴。我是Java新手,有很多代码,一些变量的名称不是英文的。我建议你翻译其中一些,以便更容易阅读。这不是一项义务,但可能会有所帮助。在我看来,有一些方法是有希望的。就像是封闭的和不相连的。也许这是一个开始?@Marc Andre No.他们会告诉你插座的状态,而不是连接。你能提供一些代码给我们吗?这样我们就可以帮助你了!我做了复制粘贴。我是Java新手,有很多代码,一些变量的名称不是英文的。我建议你翻译其中一些,以便更容易阅读。这不是一项义务,但可能会有所帮助。在我看来,有一些方法是有希望的。就像是封闭的和不相连的。也许这是一个开始?@Marc Andre No.他们会告诉你插座的状态,而不是连接状态。我想知道插座是否已连接,但没有可读取的内容,会发生什么?我对答案做了一个小更正-以防插座已连接,而没有可读取的内容,然后不会抛出异常,程序只会继续执行下一行。只有当套接字断开连接时,从套接字读取才会导致异常。这是不正确的。如果您在阻塞模式下设置了读取超时,并且没有数据,则将获得SocketTimeoutException。由您决定这是否意味着对等机处于非活动状态或网络已关闭。您引用的帖子中的答案质量很低。@EJP感谢您的评论-我将您的注释纳入了我的答案中。上面帖子中被接受的答案对我来说似乎是合理的。但是,请使用任何更简单的技术来更新此线程,以解决此问题。失去可访问性不会导致对等机断开连接。它可能会中断连接,但这不是一回事。超时异常与对等断开连接也不相同。检测客户端断开连接的最佳方法是读取并获取流的末尾,但最好的方法是
检测断开连接的方法是对其进行写入。再说一遍,这些都不是一回事。问题是关于对等断开连接,而不是关于断开的连接,我想知道套接字是否已连接但没有可读取的内容,会发生什么情况?我对答案做了一个小更正-以防套接字已连接且没有可读取的内容,然后不会抛出异常,程序只会继续执行下一行。只有当套接字断开连接时,从套接字读取才会导致异常。这是不正确的。如果您在阻塞模式下设置了读取超时,并且没有数据,则将获得SocketTimeoutException。由您决定这是否意味着对等机处于非活动状态或网络已关闭。您引用的帖子中的答案质量很低。@EJP感谢您的评论-我将您的注释纳入了我的答案中。上面帖子中被接受的答案对我来说似乎是合理的。但是,请使用任何更简单的技术来更新此线程,以解决此问题。失去可访问性不会导致对等机断开连接。它可能会中断连接,但这不是一回事。超时异常与对等断开连接也不相同。检测客户端断开连接的最佳方法是读取并获取流的结尾,但检测断开连接的最佳方法是写入。再说一遍,这些都不是一回事。问题是关于对等断开连接,而不是关于断开的连接,请参见以下答案:请参见以下答案:
package proov_server;
//SERVER 2
import java.io.*;
import java.net.*;
class server2 {
InetAddress[] kasutaja_aadress = new InetAddress[1000];
String newLine = System.getProperty("line.separator");
int kliendiNr = 0;
int kilene_kokku;
server2(int port) {
try {
ServerSocket severi_pistik = new ServerSocket(port);
System.out.println("Server töötab ja kuulab porti " + port + ".");
while (true) {
Socket pistik = severi_pistik.accept();
kliendiNr++;
kasutaja_aadress[kliendiNr] = pistik.getInetAddress();
System.out.println(newLine+"Klient " + kliendiNr + " masinast "
+ kasutaja_aadress[kliendiNr].getHostName() + " (IP:"
+ kasutaja_aadress[kliendiNr].getHostAddress() + ")");
// uue kliendi lõime loomine
KliendiLoim klient = new KliendiLoim(pistik,kliendiNr);
// kliendi lõime käivitamine
klient.start();
}
}
catch (Exception e) {
System.out.println("Serveri erind: " + e);
}
}
DataOutputStream[] väljund = new DataOutputStream[1000];
DataInputStream[] sisend = new DataInputStream[1000];
int klient = 0;
int nr;
// sisemine klass ühendusega tegelemiseks
class KliendiLoim extends Thread {
// kliendi pistik
Socket pistik;
// kliendi number
KliendiLoim(Socket pistik2,int kliendiNr) {
nr = kliendiNr;
this.pistik = pistik2;
}
public boolean kontroll(){
try{
System.out.println("con "+pistik.isConnected());
System.out.println("close "+pistik.isClosed());
if(pistik.isConnected() && !pistik.isClosed()){
//System.out.print(con_klient);
return true;
}
}catch(NullPointerException a){
System.out.println("Sihukest klienti pole!!!");
}
kliendiNr --;
return false;
}
public void run() {
try {
sisend[nr] = new DataInputStream(pistik.getInputStream()); //sisend
väljund[nr] = new DataOutputStream(pistik.getOutputStream()); //väljund
}catch (Exception ea) {
System.out.println(" Tekkis erind: " + ea);
}
while(true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Sisesta k2sk: ");
String k2sk = null;
k2sk = br.readLine();
/*
String command;
if(k2sk.indexOf(" ") < 0){
command = k2sk;
}else{
command = k2sk.substring(0, k2sk.indexOf(" "));
}
*/
String[] words = k2sk.split("\\s+");
for (int i = 0; i < words.length; i++) {
words[i] = words[i].replaceAll(" ", "");
}
switch(words[0]){
case "suhtle":
if(väljund.length > klient && väljund[klient] != null)
{
väljund[klient].writeUTF("1");
}else{
väljund[klient] = null;
sisend[klient] = null;
System.out.println("Sihukest klienti pole");
}
break;
case "vaheta":
try{
int klinetnr = Integer.parseInt(words[1]);
//if(kontroll(klinetnr) ){
klient = Integer.parseInt(words[1]);
//}
}
catch(NumberFormatException e){
System.out.println("See pole number!!! ");
}
break;
case "kliendid":
if(kliendiNr != 0){
for(int i=1;i <= kliendiNr;i++){
if(kontroll()){
System.out.println("Klient:"+i+" ip: " + kasutaja_aadress[i] );
}else{
System.out.println("Pisi");
väljund[klient] = null;
sisend[klient] = null;
}
}
System.out.println(newLine);
}else{
System.out.println("Kiente pole");
}
break;
}
System.out.println(kliendiNr);
}catch(SocketException a){
System.out.println("Klient kadus");
}
catch(Exception e){
System.out.println(" Viga: " + e);
}
}
}
}
public static void main(String[] args) {
new server2(4321);
}
}