1

設計者が想定している通常の動作から一歩外れて、Android と腕相撲をすることにうんざりしていますインターフェース コントラクトも動作的であり、パラメーターを同じに保つ場合だけではないことを付け加えたいと思います。たとえば、HONEYCOMB 以降の AsyncTask の動作の変更: デフォルトでシリアル化されたアプローチになります。

問題:

独自のアプリケーションを開発しています。それらはおそらく Play ストアに表示されることはなく、それらが実行されるすべてのデバイスを所有しています。私たちは Android デバイスを使用して、RS 232 またはイーサネット インターフェイスを介して接続されたあらゆる種類のハードウェアを駆動します。

バックグラウンド:

TCP/IP ソケットを使用して Android タブレットに定期的に (非同期に) 接続する外部デバイスがある状況があります。各接続には状態情報が関連付けられているため、(少なくとも) 2 つのアクティビティの間、IP ソケットを維持する必要があります。一般的な流れは次のとおりです。

:start
Device ----> Connect (to android device)---->Tablet 
Device ----> Send session info-------------->Tablet
Device <---- Send response<------------------Tablet
(a new activity may start here)
Device <---- Send instruction<---------------Tablet 
Device ----> Send response------------------>Tablet
Device <---- Send instruction<---------------Tablet
Device ----> Send response------------------>Tablet
Device <---- Send instruction<---------------Tablet
Device ----> Send response------------------>Tablet
goto start

上記は少し言い換えられていますが、システムの要点を示しています。

元のアプローチは、非同期接続を処理し、デバイスとの間の要求をマーシャリングする別のスレッドを使用して (アプリケーションに関連付けられた) インプロセス サービスを実行することでした。共有オブジェクトは、サーバー スレッドと接続の状態を維持していました。

ただし、フォアグラウンド アプリケーションがデバイスにコマンドを送信する必要がある場合がよくあります。これを行うには、サーバーとデバイスの間に既存の接続があることを確認し、(ソケットへの同時アクセスを防ぐために) 再入可能ロックをロックし、コマンドをデバイスに送信して応答を待つ AsyncTask を開始します。 、ほとんどすべての場合、ミリ秒以内に返されます。明らかに、UI スレッドでソケット受信を発行することはできません。そうしないと、「NetworkOnMainThreadException」が発生します (送信は正常に機能します。また、結果のポーリングは粘着性があり非効率的であるため、回避したかったのです。したがって、「 Android の「応答なし」エラーが発生する前に、デバイスが応答するかタイムアウトするとすぐに戻ります。

このアプローチは Gingerbread で完全に機能しましたが、システムを ICS 以上にアップグレードする必要があります。残念ながら、Honeycomb の北にある Android バージョンで AsyncTask を発行すると、doInBackground にヒットすることはありません。調査の結果、デフォルトでは、AsyncTask で発行されたものは、一度に 1 つのスレッドしか実行できず、プライマリ サービス スレッドが余分なスレッドとしてカウントされる可能性があるようです。(私は決定的にそれを言うものを見つけていませんが)。

デバイス インターフェイス全体を書き直すことには抵抗したいと思います。なぜなら、それは複数の製品に影響を与え、すべての製品を再テストする必要があり、ハードウェアの性質上、非常に時間のかかるプロセスになるからです。

だから、私の質問は2つあります:

1)コードを大幅に変更せずに、スレッドの制限が少ないものに AsyncTask の動作を変更する方法を知っている人はいますか?

2)そうでない場合、この種の問題に使用するより良いパターンはありますか?できれば何もポーリングする必要はありませんか?

NDA 契約の対象となっているため、コード全体を公開することはできませんが、構造に関する特定の質問がある場合は、一部のスニペットを切り取ることができます。

4

3 に答える 3

1

ここに表示されているのは、さまざまな Android バージョンでのスレッドの根本的な変更だと思います。スレッドが Android 3 の個別のコアで実行されるように作成したと思います。そして、実際の並行処理が得意なプログラマーはほとんどいないため、再びオフになった場合はオフになりました。上記の投稿をご覧いただければ、元の状態に戻すことができると思います。

ところで、これは2つではなく1つの質問に対処します。

于 2013-08-09T19:04:14.563 に答える
0

これがすべてのコードです - 問題なく動作するようですsocketserver.zip

これはビジネスの終わりです:

package com.retailsci.socketserver;

/**
 * Created with IntelliJ IDEA.
 * User: paul
 * Date: 2013/08/12
 * Time: 9:06 PM
 * To change this template use File | Settings | File Templates.
 */
import java.lang.ref.WeakReference;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.lang.InterruptedException;
import java.util.Enumeration;
import android.os.AsyncTask;
import java.io.BufferedInputStream  ;
import java.io.BufferedOutputStream ;
import java.io.OutputStreamWriter   ;

import android.app.Activity;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle ;
import android.os.IBinder ;
import android.os.RemoteException ;
import android.view.View ;
import android.view.View.OnClickListener ;
import android.widget.Button ;
import android.widget.Toast ;
import android.widget.TextView ;
import android.util.Log ;
import android.os.Handler;
import org.apache.http.conn.util.InetAddressUtils;

public class ServerThread implements Runnable
{
    public static final String    TAG = "RetailScience::ServerThread"    ;
    public static final int       READ_OPERATION        = 1 ;
    public static final int       WRITE_OPERATION       = 2 ;
    public static final int       READLENGTH_OPERATION  = 3 ;
    public static final int       WRITELENGTH_OPERATION = 4 ;

    int                           ServerPort     ;
    ServerSocket                  serverSocket   ;
    Socket                        client         ;
    boolean                       Connected      ;
    String                        IPAddress      ;
    CircularByteBuffer            InDataBuffer   ;
    CircularByteBuffer            OutDataBuffer  ;

    public ServerThread (int ServerPort)
    {
        Log.v(TAG, "constructor - start") ;

        this.ServerPort = ServerPort ;

        IPAddress = IPv4Address() ;

        Log.v(TAG, "constructor - end") ;
    }

    public boolean isConnected ()
    {
        return(Connected) ;
    }

    public String getIPAddress ()
    {
        return (IPAddress) ;
    }

    public void closeAll ()
    {
        Connected = false ; /* set the connection state */

        Log.v(TAG, "Closing all the sessions");

        try
        {
            client.close () ;
        }
        catch (Exception e)
        {
            final String error = e.getLocalizedMessage();
            Log.e(TAG, "Socket Thread - Exception on Client Close " + e.toString());
        }

        try
        {
            serverSocket.close () ;
        }
        catch (Exception e)
        {
            final String error = e.getLocalizedMessage();
            Log.e(TAG, "Socket Thread - Exception on serverSocket Close " + e.toString());
        }

        serverSocket  = null ;
        client        = null ;
        InDataBuffer  = null ;
        OutDataBuffer = null ;

        System.gc() ;

        /* Make sure the other threads can have a go now */
        Thread.yield () ;
    }

    public boolean write (byte [] data, int offset, int length)
    {
        boolean okay = false ;

        if (isConnected ())
        {
            try
            {
                OutDataBuffer.getOutputStream().write (data, offset, length) ;
                okay = true ;
                Thread.yield() ; /* Give the background thread a chance */
            }
            catch (Exception e)
            {
                final String error = e.getLocalizedMessage();
                Log.e(TAG, "UI Thread - Probably a Connection Exception " + e.toString());
            }
        }

        return (okay) ;
    }

    public void flush () /* Clear out anything in the IC buffers */
    {
        if (isConnected ())
        {
            try
            {
                int  BytesReady = 0 ;

                do
                {
                    Thread.yield() ; /* Give the background thread a chance */

                    BytesReady = InDataBuffer.getInputStream().available () ;

                    Log.v(TAG, "FLUSH bytes" + BytesReady) ;

                    if (BytesReady > 0)
                    {
                        byte[] junk = new byte [BytesReady] ;
                        InDataBuffer.getInputStream().read (junk, 0, BytesReady) ;
                    }
                    Thread.sleep (50) ; /* Give the other thread time to pull */
                                        /* anything else out of the IC buffer */
                }
                while (BytesReady > 0);

            }
            catch (Exception e)
            {
                final String error = e.getLocalizedMessage();
                Log.e(TAG, "UI Thread - Probably a Connection Exception " + e.toString());
            }
        }
    }


    public int available ()
    {
        int  BytesReady = -1 ;

        if (isConnected ())
        {
            try
            {
                BytesReady = InDataBuffer.getInputStream().available () ;

                if (BytesReady > 0)
                {
                    Log.v(TAG, "Bytes in incoming buffer " + BytesReady) ;
                }
            }
            catch (Exception e)
            {
                final String error = e.getLocalizedMessage();
                Log.e(TAG, "UI Thread - Probably a Connection Exception " + e.toString());
            }
        }

        return (BytesReady) ;
    }

    public int read (byte [] data, int offset, int length) throws IOException
    {
        int  BytesRead = -1 ;

        if (isConnected ())
        {
            Log.v(TAG, "*********  reading data " + length) ;
            try
            {
                BytesRead           = 0 ;
                int totalBytesRcvd  = 0 ; // Total bytes received so far

                while (totalBytesRcvd < length)
                {
                    if ((BytesRead =
                         InDataBuffer.getInputStream().read (data,
                                                             totalBytesRcvd + offset,
                                                             length - totalBytesRcvd)) == -1)
                    {
                        Log.e(TAG, "UI Thread Connection Exception in Read");
                        throw new SocketException("Connection closed prematurely");
                    }

                    Log.v(TAG, "*********  bytes read " + BytesRead) ;
                    totalBytesRcvd += BytesRead ;

                    Log.v(TAG, "*********  total bytes read " + totalBytesRcvd) ;
                }
                BytesRead = length ;
            }
            catch (Exception e)
            {
                final String error = e.getLocalizedMessage();
                Log.e(TAG, "UI Thread - Probably a Connection Exception " + e.toString());
            }
        }

        return (BytesRead) ;
    }

    //---get the local IPv4 address---
    // Taken from "Android(TM) Application Development Cookbook", by Wei-Meng Lee
    // p. 212
    // (Very useful book by the way)
    private String IPv4Address()
    {
        try {
            for (Enumeration<NetworkInterface> networkInterfaceEnum = NetworkInterface
                    .getNetworkInterfaces(); networkInterfaceEnum
                    .hasMoreElements();)
            {
                NetworkInterface networkInterface = networkInterfaceEnum.nextElement();

                for (Enumeration<InetAddress> ipAddressEnum
                     = networkInterface.getInetAddresses(); ipAddressEnum.hasMoreElements();)
                {
                    InetAddress inetAddress = (InetAddress) ipAddressEnum.nextElement();
                    // ---check that it is not a loopback address and
                    // it is IPv4---
                    if (!inetAddress.isLoopbackAddress()
                        &&
                        InetAddressUtils.isIPv4Address(inetAddress.getHostAddress()))
                    {
                        return inetAddress.getHostAddress();
                    }
                }
            }
        }
        catch (SocketException e)
        {
            Log.e(TAG, "IPv4Address " + e.toString());
        }
        return null;
    }

    public void run ()
    {
        try
        {
            if (IPAddress != null)
            {
                Log.v(TAG, "Starting...");
                // handler.post(new Runnable()
                //     {
                //          @Override
                //          public void run()
                //          {
                //              textView1.setText(textView1.getText()
                //                                + "Server listening on IP: " + SERVER_IP
                //                                + "\n");
                //          }
                //     });

                //---create an instance of the server socket---
                //--- Allow 2 outstanding connections
                serverSocket = new ServerSocket(ServerPort, 1);

                /* allow the socket to be reused - or we'll get INUSE exception*/
                serverSocket.setReuseAddress(true) ;

                int Counter = 0 ;
                Log.v(TAG, "Server Thread Running");

                while (true)
                {
                    //---wait for incoming clients---
                    Socket client = serverSocket.accept();

                    Log.v(TAG, "Connection Detected");
                    Connected = true ; /* set the connection state */

                    //---the above code is a blocking call;
                    // i.e. it will block until a client connects---
                    try
                    {
                        InDataBuffer                                = new CircularByteBuffer() ;
                        OutDataBuffer                               = new CircularByteBuffer() ;

                        BufferedInputStream         InStream      = new BufferedInputStream   (client.getInputStream()) ;
                        BufferedOutputStream        OutStream     = new BufferedOutputStream  (client.getOutputStream()) ;
                        int                         BytesDataBuffer ;

                        while (true)
                        {
                            if (Counter >= 1500) /* About 15 seconds */
                            {
                                /* Done' print this out too often */
                                Counter = 0 ;
                                Log.v(TAG, "Server Thread Running");
                            }
                            ++Counter ;

                            BytesDataBuffer = InStream.available() ;

                            if (BytesDataBuffer > 0)
                            {
                                Log.v(TAG, "Reading Data Bytes " + BytesDataBuffer);

                                byte [] TempBuffer = new byte [BytesDataBuffer] ;

                                InStream.read (TempBuffer, 0, BytesDataBuffer) ;
                                InDataBuffer.getOutputStream().write (TempBuffer, 0, BytesDataBuffer);

                                Log.v(TAG, "Read Data Bytes " + BytesDataBuffer);
                            }

                            BytesDataBuffer = OutDataBuffer.getInputStream().available() ;

                            if (BytesDataBuffer > 0)
                            {
                                Log.v(TAG, "Writing Data Bytes " + BytesDataBuffer);

                                byte [] TempBuffer = new byte [BytesDataBuffer] ;

                                OutDataBuffer.getInputStream().read (TempBuffer, 0, BytesDataBuffer) ;
                                OutStream.write (TempBuffer, 0, BytesDataBuffer);
                                OutStream.flush() ; /* Make sure the buffer is empty */

                                Log.v(TAG, "Wrote Data Bytes " + BytesDataBuffer);
                            }

                            Thread.sleep(100) ; /* Always yield for a bit */
                        }
                    }
                    catch (Exception e)
                    {
                        Log.e(TAG, "Socket Thread - Read Exception " + e.toString());
                        Connected = false ; /* set the connection state */
                    }

                } /*    while (true)    */
            }
            else
            {
                Log.e(TAG, "Socket Thread - No Network Capability");
                Connected = false ; /* set the connection state */
            }
        }
        catch (Exception e)
        {
            Log.e(TAG, "Socket Thread - Probably a Connection Exception" + e.toString());
            Connected = false ; /* set the connection state */
        }

        closeAll () ;
        Log.v(TAG, "*********************************************** Socket Thread - Connection Terminated");
        Log.v(TAG, "*********************************************** Socket Thread - Connection Terminated");
        Log.v(TAG, "*********************************************** Socket Thread - Connection Terminated");
        Log.v(TAG, "*********************************************** Socket Thread - Connection Terminated");
    }
}

読み取りと書き込みの例は次のとおりです: DeviceIF.java (zip ファイル内) ただし、主なプリミティブのいくつかを次に示します。

    ServerThread                  SocketIF ;
    Thread                        BackgroundThread  ;


To start it
          SocketIF         = new ServerThread (12347) ; /* 12347 is the server I/C port */
          BackgroundThread = new Thread(SocketIF);
          BackgroundThread.setDaemon(true) ; /* Make this a Daemon Thread */
          BackgroundThread.start();


To stop it                
          SocketIF.closeAll () ;
          Thread.yield () ; /* give the thread time to find out it's dead */

          if (BackgroundThread != null)
          {
             if (BackgroundThread.isAlive())
             {
                 BackgroundThread.interrupt (); /* Get rid of the thread */
                 Thread.yield () ; /* give the thread time to find out it's dead */
             }
          }

To read
        try
        {
            if (SocketIF.isConnected ())
            {
                byte []   ResponseBuffer = new byte [7] ;
                int Result = SocketIF.read (ResponseBuffer, 0, 7) ;
            }   
        }
        catch (Exception e)
        {
            final String error = e.getLocalizedMessage() ;
            Log.e(TAG, "Exception : " + error);
        }

To Write
       int Result = ERROR_FAILED ;

        try
        {
            if (SocketIF.isConnected ()) /* see if it's still open */
            {
                // flushICData () ; Good idea to do this before you issue a request

                int             RequestLen = 0 ;
                final byte []   RequestBuffer  = new byte [20] ;

                RequestBuffer [RequestLen++] = (byte) 0 ;  /* This will eventually hold the length */
                RequestBuffer [RequestLen++] = (byte) '1' ;

                RequestBuffer [0] = (byte) ((RequestLen - 1) & 0xFF) ; /* Put in the length one byte's enough */

                SocketIF.write (RequestBuffer, 0, RequestLen) ;

                Result = ERROR_OKAY ;
            }
            else
            {
                Result = ERROR_NO_CONNECTION ;
            }
        }
        catch (Exception e)
        {
            final String error = e.getLocalizedMessage() ;
            Log.e(TAG, "Exception : " + error);
            Result = ERROR_EXCEPTION ;
        }

怒りの負荷を得る前に、アーキテクチャのいくつかの欠陥に気付きました。簡単に理解できるようにシンプルにしました (これが、読み取り/書き込みをストリームにラップしなかった理由です)。読み取りにもタイムアウトを設定しませんでしたが、それを追加するのは面倒です。

他のソースから借用したコードは、ソースに示されています。

  • 作業タイマー - tick イベント内からデフォルトの android CountdownTimer をキャンセルする際に問題があるため使用されます。IP4Addess のコードは Android(TM) Application Development Cookbook から引用しました」、Wei-Meng Lee 著 p. 212 (ちなみに素晴らしい本)

(2 つ以上の f* * * リンクを投稿するのに十分な担当者がいないため、後者のコードへの URL リンクを入れることができません)

説明のために、データ ストリームへの書き込みと応答の取得の間に大幅な遅延がある場合の着信データの処理方法を次に示します。これは、Countdowntimer の onTick イベントから呼び出されます (上記のタイマー キャンセルの問題のため、私の場合は Workingtimer です)。

protected void TickHandler ()
{
    try
    {
        /* See if we have connected yet */
        if (TerminalIF.isConnected ())
        {
            /* See if we have connected yet */
            Button btn ;

            btn = (Button) findViewById (R.id.getpinbutton);
            btn.setEnabled(true) ;

            btn = (Button) findViewById (R.id.displaybutton);
            btn.setEnabled(true) ;

            btn = (Button) findViewById (R.id.getcardstatebutton);
            btn.setEnabled(true) ;

            btn = (Button) findViewById (R.id.rebootbutton);
            btn.setEnabled(true) ;

            btn = (Button) findViewById (R.id.pingbutton);
            btn.setEnabled(true) ;

            if (TerminalIF.responseReady ())
            {
                byte [] DataResult = TerminalIF.ReceivePacket () ;
                Log.v(TAG, "Data Received") ;

                Toast.makeText(getApplicationContext(),
                               "Device Data Received",
                               Toast.LENGTH_SHORT).show() ;

                resetTimer (DEFAULT_INPUT_TIMER_TIMEOUT) ;
            }
        }
    }
    catch (Exception e)
    {
        final String error = e.getLocalizedMessage() ;
        Log.e(TAG, "Exception : " + error);
    }
}

はい、AsyncTasks とハンドラーを使用してそれを行うこともできましたが、これはほとんどどこでも使用できる単純なドロップイン モジュールであり、ほとんど変更する必要はありません。サービスに変換するのもかなり簡単です。

そして、関連性がなかったり、冗長だったり、自分の質問に答えたりしたことで非難される前に、その仕事を分かち合いたいと思いました。

最後に、これを試すための小さなテスト ハーネスを次に示します。

PINPad.java

import java.io.*;
import java.net.*;
import java.lang.* ;

public class PINPad
{
    InputStream  in  ;
    OutputStream out ;

    byte [] receive (int len) throws IOException
    {
        byte [] result = null ;

        if (len > 0)
        {
            byte [] temp = new byte [len] ;

            // Receive the same string back from the server
            int totalBytesRcvd = 0; // Total bytes received so far
            int bytesRcvd ;          // Bytes received in last read

            while (totalBytesRcvd < temp.length)
            {
              if ((bytesRcvd = in.read(temp, totalBytesRcvd, temp.length - totalBytesRcvd)) == -1)
              {
                  System.out.println("Error on receive");
                  throw new SocketException("Connection closed prematurely");
              }
              else
              {
                  System.out.println("Received " + bytesRcvd + " bytes");
              }

              totalBytesRcvd += bytesRcvd;
            } // data array is full

            result = temp ;
        }

        return result ;
    }

    void send (byte [] data, int offset, int len) throws IOException
    {
        System.out.println("Sending.... " + len + " bytes");
        if (len > 0)
        {
            try
            {
                out.write (data, offset, len) ;
            }
            catch (Exception e)
            {
                System.out.println("Error on send");
                throw new SocketException("Connection closed prematurely");
            }
        }
        System.out.println("Sent " + len + " bytes");
    }

    void loop (Socket  echoSocket)
    {
        boolean okay = true ;

        try
        {
            in  = echoSocket.getInputStream();
            out = echoSocket.getOutputStream();
        }
        catch (Exception e)
        {
            okay = false ;
        }

        while (okay)
        {
            try
            {
                System.out.println("Receive length");
                byte [] len = receive (1) ;

                int packetlength = (int) len[0] ;
                System.out.println("Subsequent packet length = " + packetlength);


                byte [] packet = receive (packetlength) ;

                System.out.println("Got a packet of = " + packet.length);

                char    packettype = (char) packet [0] ;
                byte [] retbuf = new byte [50] ;
                int     reqlen = 0 ;

                switch (packettype)
                {
                    case 'A' :  /* PING */
                        System.out.println("==== PING");
                        retbuf [reqlen++] = (byte) 0 ;  /* placeholder for the length */
                        retbuf [reqlen++] = (byte) packettype ;
                        retbuf [reqlen++] = (byte) '0' ;   /* Error code  = OK */
                        retbuf [0]        = (byte) (reqlen - 1) ;  /* Now put the length in */

                        send(retbuf, 0, reqlen);
                        break ;

                    case 'B' : /* GET PIN */
                        System.out.println("==== GET PIN");
                        retbuf [reqlen++] = (byte) 0 ;  /* placeholder for the length */
                        retbuf [reqlen++] = (byte) packettype ;
                        retbuf [reqlen++] = (byte) '0' ;   /* Error code  = OK */
                        retbuf [0]        = (byte) (reqlen - 1) ;  /* Now put the length in */

                        send(retbuf, 0, reqlen);
                        break ;

                    case 'C' : /* GET CARD STATE */
                        System.out.println("==== GET CARD STATE");
                        retbuf [reqlen++] = (byte) 0 ;  /* placeholder for the length */
                        retbuf [reqlen++] = (byte) packettype ;
                        retbuf [reqlen++] = (byte) '0' ;  /* Error code  = OK */
                        retbuf [reqlen++] = (byte) '1' ;  /* Card is present */
                        retbuf [0]        = (byte) (reqlen - 1) ;  /* Now put the length in */

                        send(retbuf, 0, reqlen);
                        break ;

                    case 'D' : /* DISPLAY */
                        System.out.println("==== DISPLAY");
                        retbuf [reqlen++] = (byte) 0 ;  /* placeholder for the length */
                        retbuf [reqlen++] = (byte) packettype ;
                        retbuf [reqlen++] = (byte) '0' ;  /* Error code  = OK */
                        retbuf [0]        = (byte) (reqlen - 1) ;  /* Now put the length in */

                        send(retbuf, 0, reqlen);
                        break ;

                    case 'E' : /* REBOOT */
                        System.out.println("==== REBOOT");
                        okay = false ;
                        break ;

                    case 'F' : /* CLOSE */
                        System.out.println("==== CLOSE SESSION");
                        okay = false ;
                        break ;

                    default :
                        System.out.println("==== UNKNOWN!!!!!!");
                        retbuf [reqlen++] = (byte) 0 ;  /* placeholder for the length */
                        retbuf [reqlen++] = (byte) packettype ;
                        retbuf [reqlen++] = (byte) '3' ;  /* error */
                        retbuf [0]        = (byte) (reqlen - 1) ;  /* Now put the length in */

                        send(retbuf, 0, reqlen);
                        break ;
                }
            }
            catch (Exception e)
            {
                okay = false ;
            }
        }

        try
        {
            out.close();
            in.close();
        }
        catch (Exception e)
        {
            okay = false ;
        }
    }


    public static void main(String[] args)
    {
        Socket          echoSocket = null;
        PINPad          IF = new PINPad () ;

        while (true)
        {
            try
            {
                echoSocket = new Socket("192.168.168.106", 12347);

                // out = new PrintWriter(echoSocket.getOutputStream(), true);
                // in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));

                if (echoSocket != null)
                {
                    System.out.println("Connected to remote");
                    IF.loop (echoSocket) ;

                    echoSocket.close();
                    System.out.println("Waiting for next connection");
                }
            }
            catch (UnknownHostException e)
            {
                System.err.println("Don't know about host: 192.168.168.107.");
                // System.exit(1);
            }
            catch (IOException e)
            {
                System.err.println("Couldn't get I/O for the connection to: 192.168.168.107.");
            }
            catch (Exception e)
            {
                System.err.println("Couldn't get I/O for the connection to: 192.168.168.107.");
            }

            try
            {
                Thread.sleep (1000) ;
            }
            catch (Exception e)
            {
                System.err.println("Thread Interrupted....");
                System.exit(1);
            }
        }
    }
}
于 2013-08-13T20:34:27.887 に答える