2016-06-23 11 views
1

Javaサーバーから複数のクライアントを受け入れるためのコードは次のとおりです。JavaマルチスレッドTCPソケット - クライアントから切断されるまでのメッセージを受信します。

private class SocketServerThread extends Thread { 
     int count = 0; 
     String error_message = null; 
     @Override 
     public void run() { 
      try{ 
       serverSocket = new ServerSocket(theSocketServerPORT); 
       while (true){ 
        final Socket socket = serverSocket.accept(); 
        count++; 
        runOnUiThread(new Runnable(){ 
         @Override 
         public void run() { 
          Toast.makeText(getApplicationContext(),"New Client with IP: " + socket.getInetAddress() + " and PORT: " + socket.getPort(),Toast.LENGTH_LONG).show(); 
         } 
        }); 
        SocketServerListenToMessage socketServerListenToMessage = new SocketServerListenToMessage(socket); 
        socketServerListenToMessage.run();// Start to Receive now 
       } 
      }catch (IOException e){ 
       Log.e("IO ERROR",e.toString()); 
       error_message = "IO ERROR"; 
      }catch (Exception e){ 

       Log.e("EX ERROR",e.toString()); 
       error_message = "EX ERROR"; 
      } 
      if(error_message!=null){ 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         Toast.makeText(getApplicationContext(),error_message,Toast.LENGTH_LONG).show(); 
        } 
       }); 
      } 
     } 
    } 

クライアントが接続されたら、私はクライアントのメッセージを聞いて開始するSocketServerListenToMessageを呼び出します。

以下のコードはSocketServerListenToMessageです。

private class SocketServerListenToMessage extends Thread{ 
     Socket theClientSocket; 
     SocketServerListenToMessage(Socket clientSocketListener){ 
      theClientSocket = clientSocketListener; 
      Log.w("SERVER STATUS","Starting to Listen to Clients..."); 
     } 
     @Override 
     public void run(){ 
      try{ 
       InputStream is = theClientSocket.getInputStream(); 
       while(true){ 
        byte[] lenBytes = new byte[4]; 
        is.read(lenBytes, 0, 4); 
        int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) | 
          ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff)); 
        byte[] receivedBytes = new byte[len]; 
        is.read(receivedBytes, 0, len); 
        final String received = new String(receivedBytes, 0, len); 

        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          Toast.makeText(getApplicationContext(),"Client Says: " + received, Toast.LENGTH_LONG).show(); 
          Log.w("Client Says", received); 
         } 
        }); 
       } 
      }catch (IOException e){ 
       Log.e("IO ERR FROM LISTEN MSG", e.toString()); 
      } 
      catch (Exception e){ 
       Log.e("EX ERR FROM LISTEN MSG", e.toString()); 
      } 
     } 
    } 

上記のコードでは、複数のクライアントを接続できます。私はクライアントからMessageを受け取ることもできます。しかし問題は、First Client that is become connected to my Serverからのメッセージだけを受信できることです。 secondsoonクライアントではありませんでした。

以下のコードは私のClientからSend Messageです。私のクライアントにC#を使用しています。

IPEndPoint serverAddress; 
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //I am using Socket 

/*********To Send Message to Server**********/ 

String toSend = txt_v.Text; //The message came from TextBox. 
Task f = Task.Factory.StartNew(() => { 
    if (clientSocket.Connected) 
    { 
     int toSendLen = System.Text.Encoding.ASCII.GetByteCount(toSend); 
     byte[] toSendBytes = System.Text.Encoding.ASCII.GetBytes(toSend); 
     byte[] toSendLenBytes = System.BitConverter.GetBytes(toSendLen); 
     clientSocket.Send(toSendLenBytes); 
     clientSocket.Send(toSendBytes); 

     } 
}); 

私はこの問題は、SocketServerListenToMessagewhile loopであると思います。 while loopを削除しようとしましたが、サーバーはすべてのクライアントからメッセージを受信できましたが、クライアントごとに1つのメッセージしかありませんでした。私は、サーバが切断されるまで、クライアントのメッセージを聞くようにします。どうやってやるの?

+0

"標準のJava読み取りの問題" is.read(バッファ) 'がバッファ**のサイズまで**を読み込みましたが、保証されていません(たとえば、TCPデータストリームがストールすると、 1バイトのみ)。 DataInputStreamとそのメソッド 'readFully(..)'を確実に使うために、完全な 'byte []'を読みたいならば。 – Robert

+0

@Robert - 申し訳ありませんが、私はJavaでうまくいきません。より具体的であるか、少なくともコード例を表示できますか?ありがとう、本当にありがとうございました。 –

答えて

1

私はそれを動作させます。このおかげでLink

私が間違っていない場合、linkからシングルスレッドを使用しています。だから私のSocketServerThreadから私はちょうどそれMulti作るためにimplement Runnable代わりのThreadに必要

new Thread(new SocketServerListenToMessage(socket)).start(); 

SocketServerListenToMessage socketServerListenToMessage = new SocketServerListenToMessage(socket); 
        socketServerListenToMessage.run();// Start to Receive now 

を変更し、SocketServerListenToMessage

private class SocketServerListenToMessage implements Runnable { 
     protected Socket clientSocket = null; 

     public SocketServerListenToMessage(Socket clientSocket) { 
      this.clientSocket = clientSocket; 
     } 

     @Override 
     public void run() { 
      try { 
       while (true){ 
        InputStream is = clientSocket.getInputStream(); 
        byte[] lenBytes = new byte[4]; 
        is.read(lenBytes, 0, 4); 
        int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) | 
          ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff)); 
        byte[] receivedBytes = new byte[len]; 
        is.read(receivedBytes, 0, len); 
        final String received = new String(receivedBytes, 0, len); 

        runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          Toast.makeText(getApplicationContext(), "Client Says: " + received, Toast.LENGTH_LONG).show(); 
          Log.w("Client Says", received); 

         } 
        }); 
       } 

      } catch (IOException e) { 
       Log.e("IO ERR FROM LISTEN MSG", e.toString()); 
      } catch (Exception e) { 
       Log.e("EX ERR FROM LISTEN MSG", e.toString()); 
      } finally { 
       try{ 
        clientSocket.close(); 
        Log.w("CLIENT DISCONNECTED", "A client is disconnected."); 
       }catch (IOException e){ 
        Log.w("IO ERR DISCONNECTION", e.toString()); 
       } 
      } 
     } 
    } 

クラスを変更する必要があります。

関連する問題