2017-01-30 4 views
1

Ich bin neu in Android, etwas neues Socket-Programmierung. Ich habe zwei Geräte, läuft Android 5.1, mit WiFi direkt verbunden (nicht sicher, ob das relevant ist). Ich habe einen Dienst, bei dem der Server auf eine Anfrage auf einem Socket wartet und dann eine Antwort zurück an den Client sendet.Android WiFi Direct Client-Socket-Timeout

Ebenso sendet der Client-Code eine Anfrage und wartet auf die Antwort vom Server. Der Server sendet die Antwort, aber der Client erhält die Nachricht nie und der Socket-Timeout.

Server-Testcode:

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); 
      } 
     } 
    } 
} 

Client-Testcode:

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); 
      } 
     } 
    } 

ich den Server und Client auf zwei verschiedenen Geräten über Android Studio ausgeführt und kann in den Protokollen, dass der Server sehen empfängt die Anfrage und sendet die Antwort, aber der Client immer throwsSocketTimeoutException. Ich sah sonst, wo das socket.setKeepAlive(false) das Problem beheben würde, aber es scheint keine Wirkung zu haben.

Scheint einfach genug, aber ich kann nicht sehen, was ich hier vermisse.

Antwort

0

Figured dies aus .... Auf der Clientseite I outputStream.write(...) wurde mit der Anfrage an den Server zu senden, wie in:

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

Aber es auf dem Server mit BufferedReader.readLine() Lese:

Mein Problem war, dass outputStream.write(...) keine '\ n' am Ende der Zeichenfolge anhängen, aber in.readLine() auf dem Server erwartet es. Daher blockierte der Server während des Wartens auf '\ n'; was dazu führte, dass der Client-Socket eine Zeitüberschreitung verursachte.

0

Probieren Sie diese Codezeile vor der Endlosschleife mServer = neuer ServerSocket (PORT);

Haben Sie versucht, einen Thread in der Server-Seite App zu erstellen. Dadurch wird der Prozess parallel ausgeführt, sodass die Anwendung nicht hängen bleibt, während der Server auf eine Anforderung wartet. Versuchen Sie zunächst diesen Code für localhost. Um die Inetadresse zu finden, benutzen Sie einfach InetAddress.getLocalHost(). Dann führe das aus. Für die Kommunikation mit verschiedenen Geräten wird ein Service angeboten, der als Network Service Discovary (NSD) bezeichnet wird.

Aber wenn Sie auf diese Weise laufen wollen, habe ich einen Code für Sie geschrieben.

Server-Side-Code

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); 
    } 
} 

Client-Seite Code

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); 

    } 

Wir Handler verwendet haben, weil wir nicht Benutzeroberfläche von innen runnable in diesem Fall berühren kann. Dank

+0

Danke Sháilèndra Wregmi –

Verwandte Themen