I'm doing a desktop server application in java with multiple android clients, each one with a thread. I'm using sockets to provide the communication.
Until now, clients are sending messages to the server and then do something based on server response.
But now I need that server send a message to a specific client and I don't know how.
Could you help me please?
Thanks
Server class
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 class
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);
}
}
Main Activity
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);
}
}
The solution you suggested could be something like this?
Thanks
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();
}
}
Related
i started with android a short time ago. This time i tried to connect a c# tcp server with a java tcp client. To debug i worte a c# client and server and if i use the c# client to talk to the server, there is no problem. But my java socket has problems with connecting. I copied the java tcp code for example from the net.
c# code:
namespace MTCliserv2
{
class MTCliserv2
{
static void Main(string[] args)
{
string txt;
Console.Write("MTCliserv2 Server or Client (s/c): ");
txt = Console.ReadLine();
if (txt == "s")
Server();
else
Client();
Console.Write("\nHit any Key to continue "); Console.ReadKey();
}
static IPAddress GetIPAddress()
{
IPAddress ipAdr = Dns.Resolve("localhost").AddressList[0];
ipAdr = IPAddress.Parse("192.168.1.1");
return ipAdr;
}
static void Server()
{
TcpListener server;
Socket socke;
IPAddress ipAdr = GetIPAddress();
try
{
server = new TcpListener(ipAdr, 13);
server.Start();
Console.WriteLine("Server {0} gestartet", server.LocalEndpoint);
while (true)
{
socke = server.AcceptSocket(); // Aufruf blockiert!!
mit diesem Client abwickelt
new ConnTalk(socke);
}
}
catch (Exception e)
{
Console.WriteLine("Error {0}", e);
}
}
static void PrintConnectionInfo(Socket aSock)
{
Console.WriteLine("Anfrage von {0}", aSock.RemoteEndPoint);
}
static void Client()
{
const string serverName = "localhost";
try
{
TcpClient client = new TcpClient("192.168.1.1", 13);
NetworkStream strm = client.GetStream();
Socket sc = client.Client;
StreamReader strmRd = new StreamReader(strm);
StreamWriter strmWr = new StreamWriter(strm);
string txt, txt2;
Console.WriteLine("Connected to {0}", sc.RemoteEndPoint);
while (true)
{
Console.Write("Msg= ");
txt = Console.ReadLine();
if (txt == "end")
break;
strmWr.WriteLine(txt); strmWr.Flush();
txt2 = strmRd.ReadLine();
Console.WriteLine("Answer: {0}", txt2);
}
client.Close(); strmRd.Close(); strmWr.Close();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
// Pro Verbindung wird 1 ConnTalk-objekt erzeugt
class ConnTalk
{
Thread m_Thr;
Socket m_Sc;
public ConnTalk(Socket aSc)
{
m_Sc = aSc;
m_Thr = new Thread(this.TalkWithClient);
m_Thr.Start();
}
void TalkWithClient()
{
NetworkStream strm = new NetworkStream(m_Sc);
StreamReader strmRd = new StreamReader(strm);
StreamWriter strmWr = new StreamWriter(strm);
string txt;
Console.WriteLine("Talking with {0}", m_Sc.RemoteEndPoint);
try
{
while (true)
{
txt = strmRd.ReadLine();
Console.WriteLine("Msg: {0}", txt);
txt += " Echo!! \r\n";
strmWr.Write(txt); strmWr.Flush();
}
}
catch (Exception ex)
{
Console.WriteLine("Exception in TalkWithClient");
}
Console.WriteLine("{0} Disconnected", m_Sc.RemoteEndPoint);
m_Sc.Close(); strm.Close(); strmRd.Close(); strmWr.Close();
return;
}
}
}
And here is the java code:
package com.example.mogri.tcpsocket;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private EditText ettext;
private TextView tvlog;
TcpClient mTcpClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if ( ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.INTERNET},225);
}
if ( ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_NETWORK_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_NETWORK_STATE},225);
}
ettext = (EditText) findViewById(R.id.etText);
tvlog = (TextView) findViewById(R.id.tVlog);
Button btnsend = (Button) findViewById(R.id.btnsend);
btnsend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String input = ettext.getText().toString();
mTcpClient.sendMessage(input);
log(input);
}
});
new ConnectTask().execute("");
}
public void log(String add){
tvlog.setText( tvlog.getText()+"\n"+add);
}
public class ConnectTask extends AsyncTask<String, String, TcpClient> {
#Override
protected TcpClient doInBackground(String... message) {
//we create a TCPClient object
mTcpClient = new TcpClient(new TcpClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//response received from server
Log.d("test", "response " + values[0]);
//process server response here....
}
}
}
The tcpclient class:
package com.example.mogri.tcpsocket;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
/**
* Created by mogri on 01.04.2017.
*/
public class TcpClient {
public static final String SERVER_IP = "192.168.1.1"; //server IP address
public static final int SERVER_PORT = 13;
// 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;
public TcpClient(OnMessageReceived listener) {
mMessageListener = listener;
}
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() {
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);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
//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()));
//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);
}
}
I wrote a server for android. The Server works good and I succeed to send a message from app that simulate a client (SocketTest).
So I wrote a client in C# by my self.
I tried my client against SocketTest(As server of course) and it's work.
The connection step to android seems to be good, I get no exception.
But I don't see the message in my Android device.
C# code
{
public partial class sendSms : Form
{
TcpClient client;
NetworkStream ns;
public sendSms()
{
InitializeComponent();
}
private void Connect()
{
client = new TcpClient("192.168.14.76", 8080);
//client = new TcpClient("127.0.0.1", 8080);
ns = client.GetStream();
}
private void button1_Click(object sender, EventArgs e)
{
Connect();
}
private void sendBtn_Click(object sender, EventArgs e)
{
SendMessage();
}
private void SendMessage()
{
string sendMSG = msgTB.Text;
ns.Write(Encoding.UTF8.GetBytes(sendMSG), 0, sendMSG.Length);
ns.Flush();
}
}
}
Andorid Server
public class MainActivity extends AppCompatActivity {
private ServerSocket serverSocket;
Handler UiHandler;
Thread thread = null;
private TextView textView;
private static final int PORT = 8080;
private String status = null;
/**
* ATTENTION: This was auto-generated to implement the App Indexing API.
* See https://g.co/AppIndexing/AndroidStudio for more information.
*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
textView = (TextView) findViewById(R.id.ipTextView);
UiHandler = new Handler();
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
String ipAddress = Formatter.formatIpAddress(wifiManager.getConnectionInfo().getIpAddress());
textView.setText("Ip - " + ipAddress + ", Port - " + PORT);
// statusTxt.setText("Hello");
this.thread = new Thread(new ServerThread());
this.thread.start();
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
UiHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public String[] getPhoneAndMSG(String msg)
{
return msg.split("&");
}
class updateUIThread implements Runnable
{
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
try {
textView.setText(msg);
String[] numAndMsG = getPhoneAndMSG(msg);
// SmsManager smsManager = SmsManager.getDefault();
// Toast.makeText(getApplicationContext(), numAndMsG[0] +" " +numAndMsG[1] , Toast.LENGTH_LONG).show();
// smsManager.sendTextMessage(numAndMsG[0], null, numAndMsG[1], null, null);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "SMS Faild", Toast.LENGTH_LONG).show();
}
// textView.setText(textView.getText().toString()+"Client Says: "+ msg + "\n");
}
}
#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);
}
}
Problem solved!
string sendMSG = msgTB.Text + "\r\n";
We are developing an android application.It basically involves client server communication.Client is android phone and server is java.Client and server communication takes place.It is expected that client sends a message to the server and server responds back to the client.But in reality client is able to send the message to the server but server is unable or sends an incorrect response.I don't understand why is it happening.
Here is the client code(android):
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class MainActivity extends Activity {
private Socket client;
private PrintWriter printwriter;
private EditText textField;
public TextView accept;
private Button button;
private String message;
private static BufferedReader bufferedReader;
public static InputStreamReader inputStreamReader;
String response;
DataInputStream dis;
static String Extra_message = "hkrw.clientside";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textField = (EditText) findViewById(R.id.editText1);
button = (Button) findViewById(R.id.button1);
this.accept = (TextView) findViewById(R.id.accept);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
message = textField.getText().toString();
textField.setText("");
SendMessage sendMessageTask = new SendMessage();
sendMessageTask.execute();
accept.setText(response);
}
});
}
private class SendMessage extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
DataOutputStream dataOutputStream = null;
DataInputStream smalldataInputStream = null;
try {
client = new Socket("192.168.1.6", 4446);
printwriter = new PrintWriter(client.getOutputStream(), true);
inputStreamReader = new InputStreamReader(client.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
printwriter.write(message);
// smalldataInputStream = new DataInputStream(client.getInputStream());
printwriter.flush();
printwriter.close();
//dis= new DataInputStream(client.getInputStream());
//response=dis.readUTF();
response = bufferedReader.toString();
client.getInputStream();
// client.shutdownInput();
// client.shutdownOutput();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
#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);
}
}
Here is the code of the new activity which I have created in client side.
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class respond extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_respond);
Intent intent=getIntent();
String message = intent.getStringExtra(MainActivity.Extra_message);
TextView response;
response= (TextView) findViewById(R.id.textView1);
response.setText(message);
}
#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_respond, 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);
}
}
Here is the server code in java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.io.DataOutputStream;
public class Server {
private static ServerSocket serverSocket;
private static Socket clientSocket;
private static InputStreamReader inputStreamReader;
private static BufferedReader bufferedReader;
private static String message;
private static PrintWriter printwriter ;
static DataOutputStream dos;
public static void main(String[] args) {
String w="Hello World";
try {
serverSocket = new ServerSocket(4446); // Server socket
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
}
System.out.println("Server started. Listening to the port 4446");
while (true) {
try {
clientSocket = serverSocket.accept(); // accept the client connection
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader); // get the client message
message = bufferedReader.readLine();
System.out.println(message);
dos=new DataOutputStream(clientSocket.getOutputStream());
dos.writeUTF(w);
clientSocket.close();
System.out.println(dos);
inputStreamReader.close();
} catch (IOException ex) {
System.out.println("Problem in message reading");
}
}
}
}
this example sends a message to the server (pc in wlan),
and then gets the message back from server to phone, changing text accordingly.
change ip address of server to your pc address in wlan,
make sure to start server first, then phone app, being in that wlan
Server:
public class ChatServer implements Runnable{
private Socket socket = null;
private ServerSocket server = null;
private Thread thread = null;
private DataInputStream streamIn = null;
private DataOutputStream streamOut = null;
int port;
boolean done ;
public ChatServer(){
port = 6668;
try{
System.out.println("Gewählter Port: " + port + ", bitte warte...");
server = new ServerSocket(port);
System.out.println("Server gestartet: " + server);
start();
}
catch(IOException ioe)
{
System.out.println(ioe);
}
}
public void start(){
if (thread == null){
thread = new Thread(this);
thread.start();
}
}
public void run(){
while (thread != null){
try{
System.out.println("waiting for Client ...");
socket = server.accept();
System.out.println("Client accepted: " + socket + " IP: "+ socket.getInetAddress());
System.out.println("connecting ...");
open();
done = false;
while (!done){
try{
String line = streamIn.readUTF();
System.out.println(line);
send("Server recieved :"+line);
done = line.equals(".bye");
}
catch(IOException ioe){
done = true;
ioe.printStackTrace();
}
}
close();
}
catch(IOException ie){
System.out.println("Acceptance Error: " + ie);
}
}
}
public void send(String msg)
{
try
{
if(msg != null) {
streamOut.writeUTF(msg);
streamOut.flush();
}
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
public void open() throws IOException{
streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
streamOut = new DataOutputStream(socket.getOutputStream());
}
public void close() throws IOException{
if (socket != null) socket.close();
if (streamIn != null) streamIn.close();
if (streamOut != null) streamOut.close();
}
#SuppressWarnings("deprecation")
public void stop(){
if (thread != null){
thread.stop();
thread = null;
}
}
}
client:
public class MainActivity extends Activity implements Runnable{
EditText textUnten;
Button button;
ChatProzKlasse chat;
public static String puffer;
public static String messages;
public static TextView textMitte;
Thread thread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textMitte = (TextView) findViewById (R.id.textMitteID);
textUnten = (EditText) findViewById (R.id.textUntenID);
button = (Button) findViewById(R.id.sendButton);
messages = "";
chat = new ChatProzKlasse();
thread = new Thread(this);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chat.client.send(textUnten.getText().toString());
textUnten.setText("");
}
});
thread.start();
}
public void setTextMitte(){
runOnUiThread(new Runnable() {
#Override
public void run() {
textMitte.setText(messages);
}
});
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void run() {
while(true) {
setTextMitte();
try {
thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ChatClient {
private Socket socket = null;
private DataInputStream console = null;
private DataOutputStream streamOut = null;
private DataInputStream streamIn = null;
public static boolean isconnected = false;
public ChatClient(String serverName, int serverPort){
System.out.println("Verbindungsaufbau. Bitte warten ...");
try{
socket = new Socket(serverName, serverPort);
Log.d("DEBUG", "Connected: " + socket);
if(socket != null) {
start();
}
}
catch(UnknownHostException uhe){
Log.d("DEBUG","Host unknown: " + uhe.getMessage());
}
catch(IOException ioe){
Log.d("DEBUG","Unexpected exception: " + ioe.getMessage());
}
}
public void start() throws IOException
{
console = new DataInputStream(System.in);
streamOut = new DataOutputStream(socket.getOutputStream());
isconnected = true;
}
public void stop(){
try{
if (console != null) console.close();
if (streamOut != null) streamOut.close();
if (socket != null) socket.close();
}
catch(IOException ioe){
System.out.println("Error closing ...");
}
}
public void open() throws IOException{
streamIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}
public void close() throws IOException{
if (socket != null) socket.close();
if (console != null) console.close();
}
public void send(String msg)
{
try
{
if(msg != null) {
streamOut.writeUTF(msg);
streamOut.flush();
}
}
catch(IOException ioe)
{
Log.d("DEBUG","Sending error: " + ioe.getMessage());
}
}
public void recieve(){
try{
open();
boolean done = false;
while (!done){
try{
String line = streamIn.readUTF();
if(!(line.equals(""))) {
MainActivity.messages =line;
MainActivity.puffer = line;
}
System.out.println(" " + line);
done = line.equals(".bye");
}
catch(IOException ioe){
done = true;
ioe.printStackTrace();
}
}
close();
}
catch(IOException ie){
System.out.println("Acceptance Error: " + ie);
}
}
}
public class ChatProzKlasse implements Runnable {
Thread thread;
ChatClient client;
public ChatProzKlasse(){
thread = new Thread(this);
thread.start();
}
#Override
public synchronized void run() {
if(client == null) {
try {
System.out.println(" trying new Client");
client = new ChatClient("192.168.1.111", 6668);
} catch (Exception e) {
e.printStackTrace();
}
}
if (client !=null){
if(client != null && ChatClient.isconnected) {
client.recieve();
}
}
}}
I develope a simple chat app with login and register.
For the communication I use TCP Client and a TCP Server.
If user click to login I connect to the server.
Now I need to check if connected or not. If returns true I start a new intent.
I don't have rooted android phone to see the logs and my computer is to low for the emulator, but maybe the fail can you see in the source.
If the progress dialog done loaded is the app crash. Maybe I need a Exception..
Login:
public void LoginUser() {
class AttemptLogin extends AsyncTask<String, Void, Boolean> {
ProgressDialog pDialog;
private Context context;
public AttemptLogin(Activity activity) {
context = activity;
pDialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.setMessage(context.getString(R.string.login) + "...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Boolean doInBackground(String... args) {
session = new Session(getBaseContext(), "Azcaq", "Azcaq $$", "Test");
session.client = new TcpClient(new TcpClient.OnMessageReceived() {
#Override
public void messageReceived(String message) {
}
});
session.client.run();
Login();
return null;
}
protected void onPostExecute(final Boolean success) {
pDialog.dismiss();
}
}
new AttemptLogin(this).execute();
}
public void Login() {
if(session.client.isConnected()) {
session.setLogin(true);
Intent intent = new Intent(this, ChatsActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(getApplicationContext(), getString(R.string.connectionfail), Toast.LENGTH_LONG).show();
}
}
TcpClient
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
public class TcpClient {
public static final String SERVER_IP = "82.168.0.198";
public static final int SERVER_PORT = 64000;
private String mServerMessage;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
private PrintWriter mBufferOut;
private BufferedReader mBufferIn;
private Boolean connected = false;
public TcpClient(OnMessageReceived listener) {
mMessageListener = listener;
}
public void sendMessage(String message) {
if (mBufferOut != null && !mBufferOut.checkError()) {
mBufferOut.println(message);
mBufferOut.flush();
}
}
public Boolean isConnected() {
if(connected) {
return true;
}
return false;
}
public void stopClient() {
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
connected = false;
}
public void run() {
mRun = true;
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if(socket.isConnected()) {
connected = true;
}
while (mRun) {
try {
mServerMessage = mBufferIn.readLine();
if (mServerMessage != null && mMessageListener != null) {
mMessageListener.messageReceived(mServerMessage);
}
} catch (SocketTimeoutException e) {
} catch (IOException e) {
}
}
} catch (SocketException e) {
} catch (Exception e) { } finally {
socket.close();
}
} catch (Exception e) {
}
}
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
MainActivity.java
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Client client = new Client();
try {
client.connect("192.168.1.10",5555);
} catch (IOException e) {
e.printStackTrace();
}
}
public void displayServerAnswer(String answer){
TextView textView = (TextView)findViewById(R.id.mainTextView);
textView.setText(answer);
}
...
Client.java
import java.net.Socket;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Observable;
public class Client extends Observable implements Runnable {
private Socket socket;
private BufferedReader br;
private PrintWriter pw;
private boolean connected;
private int port=5555; //default port
private String hostName="localhost";//default host name
public Client() {
connected = false;
}
public void connect(String hostName, int port) throws IOException {
if(!connected)
{
this.hostName = hostName;
this.port = port;
socket = new Socket(hostName,port);
//get I/O from socket
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
pw = new PrintWriter(socket.getOutputStream(),true);
connected = true;
//initiate reading from server...
Thread t = new Thread(this);
t.start(); //will call run method of this class
}
}
public void sendMessage(String msg) throws IOException
{
if(connected) {
pw.println(msg);
} else throw new IOException("Not connected to server");
}
public void run() {
String msg = ""; //holds the msg recieved from server
try {
while(connected && (msg = br.readLine())!= null)
{
//In Here I want to call MainActivity.displayServerAnswer()
//notify observers//
this.setChanged();
//notify+send out recieved msg to Observers
this.notifyObservers(msg);
}
}
catch(IOException ioe) { }
finally { connected = false; }
}
...
}
In the place I specified, I want to be able to display the server answer.
How can I get access to MainActivity instance that created client object, in order to call its method?
#hopia answer is pretty good. you also can implement the Listener Design pattern
public class Client extends Observable implements Runnable {
public interface ClientListener {
public void onAction();
}
private ClientListener mListener;
public Client(ClientListener listener) {
mListener = listener;
}
public class MainActivity extends ActionBarActivity implements ClientListener {
#Override
public void onAction(){
....do whatever you need
}
...
}
You can pass an acvtivity reference to your client in either a constructor or a set accessor method.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Client client = new Client(this);
try {
client.connect("192.168.1.10",5555);
} catch (IOException e) {
e.printStackTrace();
}
}
And in your java object:
MainActivity activity;
public Client(MainActivity activity) {
connected = false;
this.activity = activity;
}
...
public void run() {
String msg = ""; //holds the msg recieved from server
try {
while(connected && (msg = br.readLine())!= null)
{
//In Here I want to call MainActivity.displayServerAnswer()
activity.displayServerAnswer();
//notify observers//
this.setChanged();
//notify+send out recieved msg to Observers
this.notifyObservers(msg);
}
}
catch(IOException ioe) { }
finally { connected = false; }
}
How about passing the activity instance as an argument to the Client's constructor?
// MainActivity
Client client = new Client(this);
// Client
public Client(Activity activity) {
this.activity = activity;
connected = false;
}