2017-01-30 5 views
1

私はAndroidには新しく、ソケットプログラミングには多少新しいです。私は2台のデバイスを持っていて、Android 5.1を実行し、WiFiダイレクトに接続しています(関連性があるかどうかはわかりません)。サーバーがソケット上の要求をリッスンしてから、クライアントに返信します。Android WiFiのダイレクトクライアントソケットのタイムアウト

同様に、クライアントコードは要求を送信し、サーバーからの応答をリッスンします。サーバーは応答を送信していますが、クライアントはメッセージを受け取ることはなく、ソケットはタイムアウトします。

Serverテストコード:

while (true) { 
    try { 
     Log.i(TAG, "test waiting for a request"); 
     mServer = new ServerSocket(PORT); 
     Socket socket = mServer.accept(); //Block to receive message // 
     BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     Log.i(TAG, "Message received! " + in.readLine()); 

     String msg = "This is my reply."; 
     OutputStream outputStream = socket.getOutputStream(); 
     PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 
     out.println(msg); 
     out.flush(); 
     out.close(); 

    } catch (SocketException e) { 
     Log.e(TAG, "Socket Accept Interrupted", e); 
    } catch (IOException e) { 
     Log.e(TAG, "Socket Failure", e); 
    } finally { 
     if (mServer != null && mServer.isBound()) { 
      try { 
       mServer.close(); 
      } catch (IOException ioException) { 
       Log.e(TAG, "Failed to close socket trying to recover from SocketException", ioException); 
      } 
     } 
    } 
} 

クライアントのテストコード:私はAndroidのメーカーを介して2つの異なるデバイス上のサーバーとクライアントを実行していることだし、ログに見ることができます

Socket socket = null; 
    SocketAddress addr = new InetSocketAddress(host, PORT); 
    int socketTOms = 5000; 
    try { 
     socket = new Socket(host, PORT); 
     socket.setKeepAlive(false); 
     String syncReq = "Request to server."; 

     //Send Request// 
     OutputStream outputStream = socket.getOutputStream(); 
     outputStream.write(syncReq.getBytes()); 
     socket.setSoTimeout(socketTOms); 

     //Rcv reply// 
     BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     Log.i(TAG, "Message received! " + in.readLine()); 

    } catch (SocketTimeoutException e) { 
     Log.e(TAG, "Timeout while reading from socket: timeout=" + socketTOms); 
    } catch (Exception e) { 
     Log.e(TAG, "Exception", e); 
    } finally { 
     if (socket != null && socket.isConnected()) { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       Log.e(TAG, "Exception while closing socket", e); 
      } 
     } 
    } 

サーバー要求を受信して​​応答を送信しますが、クライアントは常にthrowsSocketTimeoutExceptionです。私は、そのsocket.setKeepAlive(false)が問題を解決するところを見ましたが、何の効果もないようです。

シンプルなようですが、私はここで何が欠けているのか分かりません。

答えて

0

これを考え出した.... 私はのようにサーバに要求を送信するためにoutputStream.write(...)を使用していた。

String syncReq = "Request to server."; 
    OutputStream outputStream = socket.getOutputStream(); 
    outputStream.write(syncReq.getBytes()); 

しかしBufferedReader.readLine()と、サーバー上でそれを読んで:

Socket socket = mServer.accept(); //Block to receive message // 
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    Log.i(TAG, "Message received! " + in.readLine()); 

私の問題は、outputStream.write(...)は、文字列の最後に '\ n'を追加しませんでしたが、サーバーのin.readLine()にはそれが期待されていました。したがって、サーバーは '\ n'の待機中にブロックされていました。クライアントソケットのタイムアウトが発生しました。

0

無限ループの前にこのコード行を試してくださいmServer = new ServerSocket(PORT);

サーバーサイドアプリでスレッドを作成しようとしましたか?これによりプロセスが並行して実行されるため、サーバーが要求を待機している間にアプリケーションがハングしないようにします。まず、このコードをlocalhostで試してください。 Inetaddressを見つけるには、InetAddress.getLocalHost()を使用してください。その後、これを実行します。異なるデバイスとの通信には、NSD(Network Service Discovary)と呼ばれるサービスが用意されています。

しかし、この方法で実行したい場合は、コードを作成しました。

サーバー側のコード

TextView textView; 
    Button button; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     textView=(TextView)findViewById(R.id.textView); 
     button=(Button)findViewById(R.id.button); 

button.setOnClickListener(
     new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       connect(); 
      } 
     } 
); 



    } 


    public void connect() 
    { 

     MyServer myServer= new MyServer(); 
     myServer.setEventListener(this); 
     myServer.startListening(); 

    } 





    @Override 
    public void Display(String message) { 

     textView.setText("Client - "+ message); 
    } 
} 

クライアント側のコード

TextView textView; 
    Button button; 
    Thread mThread; 
    Socket clientSocket; 
Button sendBtn; 
    public String userText1; 
    ObjectOutputStream output; 
    EditText editText; 
    Object userText; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     textView=(TextView)findViewById(R.id.textView); 
     button=(Button)findViewById(R.id.button); 
     sendBtn=(Button)findViewById(R.id.sendBtn); 
     editText=(EditText)findViewById(R.id.editText); 
     sendBtn.setOnClickListener(
       new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
         userText=editText.getText().toString(); 


         start(); 
        } 
       } 
     ); 




    public void start() 
    { 
     mThread= new Thread(new Runnable() { 
      @Override 
      public void run() { 

       try { 
        clientSocket = new Socket("127.0.0.1", 2001); 
        Log.v("binaya", "client socket created"); 
        output = new ObjectOutputStream(clientSocket.getOutputStream()); 
        output.writeObject(userText); 
        Message serverObj = Message.obtain(); 
        ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream()); 


        String strMsg = input.readObject().toString(); 
        serverObj.obj = strMsg; 

        mHandler.sendMessage(serverObj); 

       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (ClassNotFoundException e) { 
        e.printStackTrace(); 
       } 


      } 
     }); 
    mThread.start(); 
    } 


    Handler mHandler= new Handler() 
    { 
     @Override 
     public void handleMessage(Message msg) { 
      msgDisplay(msg.obj.toString()); 
     } 
    }; 

    private void msgDisplay(String msg) { 
    textView.setText("Server - " + msg); 

    } 

我々はこのケースで実行可能な内部からのユーザーインターフェースに触れることができないので、我々は、ハンドラを使用しています。クライアント側では おかげ

+0

ありがとうSháilèndraWregmi –