我在java中使用多个Android客户端进行桌面服务器应用程序,每个客户端都有一个线程。我正在使用套接字来提供通信。
到目前为止,客户端正在向服务器发送消息,然后根据服务器响应执行某些操作。
但现在我需要服务器向特定客户端发送消息,我不知道如何。
你能帮我吗?
谢谢
服务器类
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类
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);
}
}
主要活动
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 :(得分:0)
您建议的解决方案可能是这样的吗?
由于
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();
}
}