ソケットが接続されているかどうかを判断し、異常にネットワークケーブルを切断します.

9864 ワード

転載は出典を明記してください.http://blog.csdn.net/xx326664162/article/details/48522381文の出典:薛スーのブログ
あなたも私の他の同類の文章を見ることができて、あなたにも一定の出荷があります!
  • setSoTimeout
  •  public void setSoTimeout(int timeout)
                throws SocketException 

    指定したタイムアウト値を持つSO_の有効化/無効化TIMEOUT、ミリ秒単位.このオプションをゼロ以外のタイムアウト値に設定すると、このSocketに関連付けられたInputStreamでread()を呼び出すと、この時間の長さだけがブロックされます.タイムアウト値を超えるとjavaが開始する.net.SocketTimeoutException、Socketは依然として有効ですが.オプションを有効にするには、ブロック操作に入る前に有効にする必要があります.タイムアウト値は>0の数でなければなりません.タイムアウト値が0の場合は、無限大タイムアウト値として解釈されます.≪パラメータ|Parameters|emdw≫:timeout-ミリ秒単位のタイムアウト値を指定します.放出:SocketException-TCPエラーなどの下位プロトコルにエラーが発生した場合.
    タイムアウト時間保持接続を設定し、read()関数を呼び出さない限り、タイムアウトプログラムでも例外は放出されません.
  • connect
  • public void connect(SocketAddress endpoint,
                          int timeout)
                   throws IOException 

    このソケットをサーバに接続し、タイムアウト値を指定します.タイムアウト値ゼロは無限タイムアウトと解釈される.接続が確立されるか、エラーが発生するまで、接続はブロックされたままです.パラメータ:endpoint-SocketAddress timeout-使用するタイムアウト値(ミリ秒単位).放出:IOException-
  • 接続中にエラーが発生した場合
  • 接続前に期間が経過した場合IllegalBlockingModeException
  • このソケットに関連するチャネルがあり、非ブロックモードである場合IllegalArgumentException
  • .
  • エンドポイントがnullである場合、またはこのソケットがSocketAddressサブクラス
  • をサポートしない場合.
  • ハートビートパケットとは、クライアントとサーバとの間でタイミングを決めて相手に自分の状態を知らせる独自の定義されたコマンドワードで、一定の時間間隔で送信され、ハートビートに似ているので、ハートビートパケットと呼ばれます.
  • は、相手(デバイス、プロセス、または他のネットワーク)が正常に動作しているかどうかを判断し、TCPの異常切断を検出するために使用される.
  • の基本的な原因は、サーバ側がクライアントがオンラインであるか否かを効果的に判断できないこと、すなわち、サーバがクライアントが長時間アイドルであるか、またはオフラインであるかを区別できないことである.
  • いわゆるハートビートパケットとは、クライアントが時間通りに簡単な情報をサーバ側に送って、私がまだいることを伝えることです.コードは数分おきに固定情報をサービス側に送信し、サービス側が受信した後に固定情報に返信する.サービス側が数分以内にクライアント情報を受信しなければ、クライアントによって切断される.
  • 発注者:取引先でもサービス側でも、どちらが便利で合理的かを見て、一般的にはクライアントです.サーバーも定期的にドキドキすることができます.一般的に、効率的な観点から、サーバがクライアントに送信するのではなく、クライアントがサーバ側に送信する.クライアントは一定の時間ごとに1つのパケットを出して、TCPのを使って、sendで送って、UDPのを使って、sendtoで送って、サーバーが受け取った後に、現在のクライアントがまだ“生きている”状態にあることを知っていて、さもなくば、一定の時間隔ててこのようなパケットを受け取っていないならば、サーバーは客先がすでに切れたと思って、相応のクライアントが論理処理を切断します!
  • はもちろん、心拍数パケットが相手にデータをリラックスさせることを単純に理解することはできません.心拍数パケットは状態検証に使用され、真実のデータではないからです.

  • 正常に接続を切断し、この関数は異常
  • を放出します.
  • サーバネットワークが異常に切断されたと判断できません.たとえば、ネットワークケーブルを抜いてください.sendUrgentData()関数を使用すると、直接ネットワーク線を抜く場合でも異常情報は放出されません.この関数は緊急データを送信するだけで、
  • です.
    socket.sendUrgentData(0xFF); //      

    サービス:
    package com.service;  
    import java.net.*;  
    /** 
     - @                    
     */  
    public class DstService {  
        public static void main(String[] args) {  
            try {             
                //        8001  
                ServerSocket ss = new ServerSocket(8001);  
                //                
                Socket s = ss.accept();  
                //               
                new Thread(new DstServiceImpl(s)).start();  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    } 

    サービス側実行クラス:
    package com.service;  
    import java.net.Socket;  
    /** 
     * @            
     */  
    public class DstServiceImpl implements Runnable {  
        Socket socket = null;  
        public DstServiceImpl(Socket s) {  
            this.socket = s;  
        }  
        public void run() {  
            try {  
                int index = 1;  
                while (true) {  
                    // 5        
                    if (index > 5) {  
                        socket.close();  
                        System.out.println("          !");  
                        break;  
                    }  
                    index++;  
                    Thread.sleep(1 * 1000);  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    } 

    クライアントのテスト1:
    package com.client;  
    import java.net.*;  
    /** 
     * @         ,                   ,          
     */  
    public class DstClient {  
        public static void main(String[] args) {  
            try {  
                Socket socket = new Socket("127.0.0.1", 8001);  
                socket.setKeepAlive(true);  
                socket.setSoTimeout(10);  
                while (true) {  
                    System.out.println(socket.isBound());  
                    System.out.println(socket.isClosed());  
                    System.out.println(socket.isConnected());  
                    System.out.println(socket.isInputShutdown());  
                    System.out.println(socket.isOutputShutdown());  
                    System.out.println("------------------------");  
                    Thread.sleep(3 * 1000);  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    } 

    5秒後、サービス側は切断されましたが、クライアントはコンテンツを出力し続けました.
    true  
    false  
    true  
    false  
    false  
    ------------------------  

    サーバが切断されているかどうかを判断する際には、まずsocketクラスのメソッドisClosed()やisConnected()やisInputStreamShutdown()やisOutputStreamShutdown()などが考えられますが、これらのメソッドはいずれもローカル側の状態であり、リモート側が切断されているかどうかを判断することはできません.
    クライアント2のテスト:
    package com.client;  
    import java.net.*;  
    /** 
     * @      ,                   ,           
     */  
    public class DstClient {  
        public static void main(String[] args) {  
            try {  
                Socket socket = new Socket("127.0.0.1", 8001);  
                socket.setKeepAlive(true);  
                socket.setSoTimeout(10);  
                while (true) {  
                    socket.sendUrgentData(0xFF); //        
                    System.out.println("      !");  
                    Thread.sleep(3 * 1000);  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }

    このリンクではsendUrgentData(0 xFF)とin.readLine(); どちらの方法も,サーバがシャットダウンしたときに断線した場合(正常に切断した場合)しか判断できず,直接ネットワークを抜く操作は判断できない.
    上記のプログラムは単一スレッドであることに注意してください.接続を切断してクライアントが接続すると、サービス側で「サービス側は接続を閉じました!」と印刷できません.詳しい原因はこのブログに参加してください
    参照先:http://cuisuqiang.iteye.com/blog/1453632 http://www.apkbus.com/android-142289-1-1.html
    私の公衆番号に注目して、もっと多くの技術を簡単に理解して勉強します.