2016-06-06 5 views
0

Ich mache eine Desktop-Server-Anwendung in Java mit mehreren Android-Clients, jeweils mit einem Thread. Ich verwende Sockets, um die Kommunikation zu ermöglichen.Mehrere Client-Server Android

Bis jetzt senden Clients Nachrichten an den Server und dann etwas basierend auf der Serverantwort.

Aber jetzt brauche ich diesen Server eine Nachricht an einen bestimmten Client senden und ich weiß nicht wie.

Könnten Sie mir bitte helfen?

Dank

Server Klasse

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

public class Server { 

    public static void main(String[] args) throws IOException{ 

     boolean listening = true; 

     try (ServerSocket serverSocket = new ServerSocket(4444)){ 

      while(listening){ 
       new ServerThread(serverSocket.accept()).start(); 
      } 
     } catch (IOException e) { 
      System.out.println("Could not listen on port: 4444"); 
      System.exit(-1); 
     } 

    } 
} 

Serverthread

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

public class ServerThread extends Thread { 

    private Socket socket = null; 

    public ServerThread(Socket socket) { 
     super("ServerThread"); 
     this.socket = socket; 
    } 

    public void run() { 

     try (
      PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 
      BufferedReader in = new BufferedReader(
       new InputStreamReader(
        socket.getInputStream())); 
     ) { 
      String inputLine, outputLine; 
      GameProtocol gp = new GameProtocol(); 
      outputLine = gp.processInput(null); 
      //System.out.println(outputLine); 
      //out.println(outputLine); 

      while ((inputLine = in.readLine()) != null) { 
       //System.out.println(outputLine); 
       outputLine = gp.processInput(inputLine); 
       System.out.println(outputLine); 
       out.println(outputLine); 
       if (outputLine.equals("Bye")) 
        break; 
      } 
      socket.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

TcpClient Klasse

import android.util.Log; 

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

/** 
* Created by andrecorreia on 03/06/16. 
*/ 
public class TcpClient { 

    public static final String SERVER_IP = "10.0.2.2"; // computer IP address 
    public static final int SERVER_PORT = 4444; 

    // message to send to the server 
    private String mServerMessage; 
    // sends message received notifications 
    private OnMessageReceived mMessageListener = null; 
    // while this is true, the server will continue running 
    private boolean mRun = false; 
    // used to send messages 
    private PrintWriter mBufferOut; 
    // used to read messages from the server 
    private BufferedReader mBufferIn; 

    /** 
    * Constructor of the class. OnMessagedReceived listens for the messages received from server 
    */ 
    public TcpClient(OnMessageReceived listener) { 
     mMessageListener = listener; 
    } 

    /** 
    * Sends the message entered by client to the server 
    * 
    * @param message text entered by client 
    */ 
    public void sendMessage(String message) { 
     if (mBufferOut != null && !mBufferOut.checkError()) { 
      mBufferOut.println(message); 
      mBufferOut.flush(); 
     } 
    } 

    /** 
    * Close the connection and release the members 
    */ 
    public void stopClient() { 
     Log.i("Debug", "stopClient"); 

     // send mesage that we are closing the connection 
     //sendMessage(Constants.CLOSED_CONNECTION + "Kazy"); 

     mRun = false; 

     if (mBufferOut != null) { 
      mBufferOut.flush(); 
      mBufferOut.close(); 
     } 

     mMessageListener = null; 
     mBufferIn = null; 
     mBufferOut = null; 
     mServerMessage = null; 
    } 

    public void run() { 

     mRun = true; 

     try { 
      //here you must put your computer's IP address. 
      InetAddress serverAddr = InetAddress.getByName(SERVER_IP); 

      //InetAddress serverAddr = InetAddress.getLocalHost(); 
      Log.e("TCP Client", "C: Connecting..."); 

      //create a socket to make the connection with the server 
      Socket socket = new Socket("192.168.1.92", SERVER_PORT); 

      try { 
       Log.i("Debug", "inside try catch"); 
       //sends the message to the server 
       mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 

       //receives the message which the server sends back 
       mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       // send login name 
       //sendMessage(Constants.LOGIN_NAME + PreferencesManager.getInstance().getUserName()); 
       //sendMessage("Hi"); 
       //in this while the client listens for the messages sent by the server 
       while (mRun) { 
        mServerMessage = mBufferIn.readLine(); 
        if (mServerMessage != null && mMessageListener != null) { 
         //call the method messageReceived from MyActivity class 
         mMessageListener.messageReceived(mServerMessage); 
        } 

       } 
       Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'"); 

      } catch (Exception e) { 

       Log.e("TCP", "S: Error", e); 

      } finally { 
       //the socket must be closed. It is not possible to reconnect to this socket 
       // after it is closed, which means a new socket instance has to be created. 
       socket.close(); 
      } 

     } catch (Exception e) { 

      Log.e("TCP", "C: Error", e); 

     } 

    } 

    //Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity 
    //class at on asynckTask doInBackground 
    public interface OnMessageReceived { 
     public void messageReceived(String message); 
    } 
} 

Hauptaktivität

import android.app.Activity; 
import android.content.Intent; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.View.OnClickListener; 


public class MainActivity extends Activity implements OnClickListener { 

    public static TcpClient tcpClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     new ConnectTask().execute(""); 

     // Set up click listeners for all the buttons 
     View playNowButton = findViewById(R.id.playNow_button); 
     playNowButton.setOnClickListener(this); 

     View optionsButton = findViewById(R.id.options_button); 
     optionsButton.setOnClickListener(this); 

     View helpButton = findViewById(R.id.help_button); 
     helpButton.setOnClickListener(this); 

     View exitButton = findViewById(R.id.exit_button); 
     exitButton.setOnClickListener(this); 
     //--------------------------------------------- 
    } 


    @Override 
    public void onClick(View v) { 
     Intent i; 
     switch (v.getId()){ 
      case R.id.playNow_button: 
       i = new Intent(this, PlayNowActivity.class); 
       startActivity(i); 
       break; 
      case R.id.options_button: 
       i = new Intent(this, OptionsActivity.class); 
       tcpClient.sendMessage("options"); 
       startActivity(i); 
       break; 
      case R.id.help_button: 
       i = new Intent(this, HelpActivity.class); 
       tcpClient.sendMessage("help"); 
       startActivity(i); 
       break; 
      case R.id.exit_button: 
       finish(); 
       break; 
     } 
    } 

    public class ConnectTask extends AsyncTask<String,String,TcpClient> { 

     @Override 
     protected TcpClient doInBackground(String... message) { 

      //we create a TCPClient object and 
      tcpClient = new TcpClient(new TcpClient.OnMessageReceived() { 
       @Override 
       //here the messageReceived method is implemented 
       public void messageReceived(String message) { 

        //this method calls the onProgressUpdate 
        publishProgress(message); 

       } 
      }); 
      tcpClient.run(); 

      return null; 
     } 

     @Override 
     protected void onProgressUpdate(String... values) { 
      super.onProgressUpdate(values); 
     /*View view = adapter.getChildView(0, 0, false, null, null); 
     TextView text = (TextView) view.findViewById(R.id.betChildOdd); 
     child2.get(0).get(0).put("OLD", text.getText().toString()); 
     child2.get(0).get(0).put(CONVERTED_ODDS, values[0].toString()); 
     child2.get(0).get(0).put("CHANGE", "TRUE"); 
     adapter.notifyDataSetChanged();*/ 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.menu_main, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     //noinspection SimplifiableIfStatement 
     if (id == R.id.action_settings) { 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

} 
+0

Hallo. Können Sie mir bitte sagen, was damit nicht stimmt? Oder wie könnte ich es richtig machen? Danke – agfac

+1

Ihr Server benötigt 2 Threads pro Client oder einen dedizierten Sende-Thread. Sie sind derzeit in 'in.readLine()' stecken und können nicht senden. Mit einem zusätzlichen zu sendenden Thread können Sie Nachrichten von außen in Warteschlangen stellen (mit einem "BlockingQueue", klassisches Producer-Consumer-Szenario) und zu jedem Zeitpunkt entscheiden, Daten zu senden, während der Lesecode das Warten nicht unterbrechen muss. – zapl

+0

@zapi danke, dass du mir geholfen hast. Können Sie mir bitte sagen, wie ich 2 Threads pro Client machen könnte? Danke – agfac

Antwort

0

Die Lösung, die Sie so etwas wie dies vorgeschlagen könnte?

Dank

public class Server { 

    private static ArrayList<ServerThread> playerList; 
    private static LinkedBlockingQueue<Object> messages; 
    private static GameProtocol gp ; 

    public static void main(String[] args) throws IOException{ 

     playerList = new ArrayList<ServerThread>(); 
     messages = new LinkedBlockingQueue<Object>(); 
     gp = new GameProtocol(); 

     Thread accept = new Thread() { 
      public void run(){ 
       while(true){ 
        try{ 
         ServerSocket serverSocket = new ServerSocket(4444); 
         ServerThread player = new ServerThread(serverSocket.accept(), gp); 
         playerList.add(player); 
         player.start(); 

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

     accept.setDaemon(true); 
     accept.start(); 

     Thread messageHandling = new Thread() { 
      public void run(){ 
       while(true){ 
        try{ 
         Object message = messages.take(); 
         // Do some handling here... 
         System.out.println("Message Received: " + message); 
        } 
        catch(InterruptedException e){ } 
       } 
      } 
     }; 

     messageHandling.setDaemon(true); 
     messageHandling.start(); 
    } 
}