I am developing a client server application. My client is a java application and my server is an android emulator. I want to send message from client to server but no message received on android emulator.
Java Desktop Client Code
Socket s = null;
BufferedReader get = null;
PrintWriter put = null;
try {
s = new Socket("127.0.0.1", 6000);
put = new PrintWriter(s.getOutputStream(), true);
put.println("hi");
}
catch(Exception ex)
{
}
Android Server Code
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
private EditText textbox;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} 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();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
Relevant quote from the documentation (scroll down to the section for Network Address Space:
Each instance of the emulator runs behind a virtual router/firewall service
that isolates it from your development machine's network interfaces and settings
and from the internet. An emulated device can not see your development machine
or other emulator instances on the network. Instead, it sees only that it is
connected through Ethernet to a router/firewall.
The virtual router for each instance manages the 10.0.2/24 network address
space — all addresses managed by the router are in the form of 10.0.2.<xx>,
where <xx> is a number. Addresses within this space are pre-allocated by the
emulator/router as follows:
And then they proceed to show the pre-allocated addresses in a table.
Related
I'm beginer in android and i'm trying develop a connection TCP server.
I have this class:
public class JavaTCPServer {
public static void send(String aMessage) {
final String msg = aMessage;
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
try {
ServerSocket serverSocket = GlobalSingleton.getInstance().getServerSocket();
socket = serverSocket.accept();
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
printWriter.println(msg);
printWriter.flush();
printWriter.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
socket = null;
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
});
thread.start();
}
}
private ServerSocket serverSocket; //Created in GlobalSingleton Class...
try {
serverSocket = new ServerSocket(Constantes.TCP_PORT);
} catch (IOException e) {
e.printStackTrace();
}
I can send message normally in the first time, but when i try to send message the second time the software remains in line: socket = serverSocket.accept(); and the message in printWriter.println(msg) is not sent.
Additional Information
When i kill the app in settings and open i can send once.
Any questions don't hesitate ask me.
Thanks for all!
Your code only accepts one connection, processes it, and then exits. It does not behave as you have described.
You need a loop.
You also need to start a separate thread to handle each connection.
And calling a method that accepts connections send() is inside out and back to front.
I solved my own problem.
I wrote my class as the follow bellow code:
public class JavaTCPServer {
private ServerSocket serverSocket;
private String message;
private Handler updateConversationHandler;
private Thread serverThread = null;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ServerSocket getServerSocket() {
return serverSocket;
}
public void setServerSocket(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
}
public JavaTCPServer() {
setUpdateConversationHandler(new Handler());
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
public Handler getUpdateConversationHandler() {
return updateConversationHandler;
}
public void setUpdateConversationHandler(Handler updateConversationHandler) {
this.updateConversationHandler = updateConversationHandler;
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(Constantes.TCP_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;
private String messageSend;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.setInput(new BufferedReader(new InputStreamReader(
this.clientSocket.getInputStream())));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
Central central = GlobalSingleton.getInstance()
.get_current_central();
if (central != null) {
if ((central.getStep() <= central.getObjetivo()) &&
(central.getStep() == 99)){
try {
messageSend = getMessage();
PrintWriter printWriter = new PrintWriter(
clientSocket.getOutputStream(), true);
printWriter.println(messageSend);
printWriter.flush();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
printWriter.println(Constantes.EXIT_CONFIG);
printWriter.flush();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
central.setStep(central.getStep() + 1);
}
}
/*
* try { String read = input.readLine();
* updateConversationHandler.post(new updateUIThread(read)); }
* catch (IOException e) { e.printStackTrace(); }
*/
}
}
public BufferedReader getInput() {
return input;
}
public void setInput(BufferedReader input) {
this.input = input;
}
}
}
With this class you can send and receive tcp messages all the time.
Thanks for all help!
Serversocket.accept() function is for accepting a new client and connecting with the client, for messages you need to use DataInputStream() and DataOutputStream() after connecting with the server. This happens because for the first time server accepts the new client and process further but after this it does not get a new connection and it waits for new connection at serversocket.accept().
I'm trying to connect 2 android device (without server in the middle, just directly like peer-to-peer) which are connected to internet(they are far apart) and send messages.
I thought its like normal socket programming, and connects via IP, seems not.
what I have done so far is this:
I have created 2 android projects, server(receiver) and client(sender)
running in 2 separate devices
Both devices are connected to internet
found the IP of the device with server app running in (using whatismyip.com)
and used it in client app code
but when I want to send a text from client to server, an exception happens in client printing Error3
this is my code:
server:
public class MainActivity extends Activity {
ServerSocket ss = null;
String mClientMsg = "";
Thread myCommsThread = null;
protected static final int MSG_ID = 0x1337;
public static final int SERVERPORT = 6000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.TextView01);
tv.setText("Nothing from client yet");
this.myCommsThread = new Thread(new CommsThread());
this.myCommsThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
// make sure you close the socket upon exiting
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Handler myUpdateHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_ID:
TextView tv = (TextView) findViewById(R.id.TextView01);
tv.setText(mClientMsg);
break;
default:
break;
}
super.handleMessage(msg);
}
};
class CommsThread implements Runnable {
public void run() {
Socket s = null;
try {
ss = new ServerSocket(SERVERPORT );
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
Message m = new Message();
m.what = MSG_ID;
try {
if (s == null)
s = ss.accept();
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String st = null;
st = input.readLine();
mClientMsg = st;
myUpdateHandler.sendMessage(m);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Client (Error3):
public class MainActivity extends Activity {
private Button bt;
private TextView tv;
private Socket socket;
private String serverIpAddress = "5.114.22.118";
// AND THAT'S MY DEV'T MACHINE WHERE PACKETS TO
// PORT 5000 GET REDIRECTED TO THE SERVER EMULATOR'S
// PORT 6000
private static final int REDIRECTED_SERVERPORT = 80;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt = (Button) findViewById(R.id.myButton);
tv = (TextView) findViewById(R.id.myTextView);
new Thread(new ClientThread()).start();
bt.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(str);
Log.d("Client", "Client sent message");
} catch (UnknownHostException e) {
tv.setText("Error1");
e.printStackTrace();
} catch (IOException e) {
tv.setText("Error2");
e.printStackTrace();
} catch (Exception e) {
tv.setText("Error3");
e.printStackTrace();
}
}
});
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
I think this would be more appropriate as a comment, but I don't have enough reputation to comment so I'm providing it as an answer. Is your server connected to a router? whatismyip.com returns the IP address of the router, not the device.
This question has been asked quite a few times here , but there is no good answer yet.So I am just posting this question along with my progress. I would like to know if there is a way to perform socket programming between a real device and emulator.
I referred to android developer page : http://developer.android.com/tools/devices/emulator.html
to establish communication between two android devices / and also between two emulators. But there is no way I am able to send data from android device(client) to emulator(as the server). Both of them are connected to the same network and are able to ping each other.
public class ServerActivity extends Activity {
private TextView serverStatus;
private Button Start;
private Button Mark;
private Button Stop;
// DEFAULT IP
public static String SERVERIP = "10.0.2.15";
// DESIGNATE A PORT
public static final int SERVERPORT = 6000;
private Handler handler = new Handler();
private ServerSocket serverSocket;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverStatus = (TextView) findViewById(R.id.server_status);
Start = (Button)findViewById(R.id.start);
Mark = (Button)findViewById(R.id.mark);
Stop = (Button)findViewById(R.id.stop);
//SERVERIP = getLocalIpAddress();
Thread fst = new Thread(new ServerThread());
fst.start();
}
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Listening on IP: " + SERVERIP +" "+ SERVERPORT);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// LISTEN FOR INCOMING CLIENTS
final Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected.");
}
});
try {
handler.post(new Runnable() {
#Override
public void run() {
// DO WHATEVER YOU WANT TO THE FRONT END
// THIS IS WHERE YOU CAN BE CREATIVE
Log.d("ServerActivity", "S: Sending command.");
PrintWriter out;
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);
// WHERE YOU ISSUE THE COMMANDS
out.println("HeyClient!");
Log.d("ServerActivity", "S: Sent.");
Start.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
//send click command to start recording to client
}
});
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
break;
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
}
});
e.printStackTrace();
}
}
} else {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Couldn't detect internet connection.");
}
});
}
} catch (Exception e) {
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Error");
}
});
e.printStackTrace();
}
}
}
// GETS THE IP ADDRESS OF YOUR PHONE'S NETWORK
private String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
}
}
} catch (SocketException ex) {
Log.e("ServerActivity", ex.toString());
}
return null;
}
#Override
protected void onStop() {
super.onStop();
try {
// MAKE SURE YOU CLOSE THE SOCKET UPON EXITING
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}}
and the client code :
public class ClientActivity extends Activity {
private EditText serverIp;
private TextView serverCommand;
private Button connectPhones;
private String serverIpAddress = "";
private boolean connected = false;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
connectPhones.setOnClickListener(connectListener);
serverCommand = (TextView)findViewById(R.id.server_commands);
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
if (!connected) {
serverIpAddress = serverIp.getText().toString();
if (!serverIpAddress.equals("")) {
Thread cThread = new Thread(new ClientThread());
cThread.start();
}
}
}
};
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
Log.d("ClientActivity", "C: Connecting...");
Socket socket = new Socket(serverAddr, 80);
connected = true;
while (connected)
{
try {
String line = null;
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while ((line = in.readLine()) != null) {
Log.d("ClientActivity", line);
serverCommand.setText(line);
if (line == "start")
{
}
}
} catch (Exception e) {
Log.e("ClientActivity", "S: Error", e);
}
}
socket.close();
Log.d("ClientActivity", "C: Closed.");
} catch (Exception e) {
Log.e("ClientActivity", "C: Error", e);
connected = false;
}
}
}
}
I also set up port forwarding to direct incoming connections from android at port 80 to emulator at port 6000. This is was done using telnet.
For some reason, all this doesn't seem to make emulator connect to the incoming connections.
I would be really grateful if someone could help me out.
Credits : Code from http://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/
I use these codes for communicating between devices. If i close or kill the client app, the server app gets thousands of useless data. The textView in the server side is full of this: Client says: null. If i close the client twice, the server stops with StackOverFlowError. How can i make the code to dont send this null values when the app stops? Or can i filter the server side to do nothing when getting this data?
Client:
public class Client extends Activity {
private Socket socket;
private static final int SERVERPORT = 5000;
private static final String SERVER_IP = "10.0.2.2";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new ClientThread()).start();
}
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Server:
public class Server extends Activity {
private ServerSocket serverSocket;
Handler updateConversationHandler;
Thread serverThread = null;
private TextView text;
public static final int SERVERPORT = 1599;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView) findViewById(R.id.text2);
updateConversationHandler = new Handler();
this.serverThread = new Thread(new ServerThread());
this.serverThread.start();
}
#Override
protected void onStop() {
super.onStop();
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} 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();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(text.getText().toString()+"Client Says: "+ msg + "\n");
}
}
}
I think you should use a delimiter character, to tell the Server your Client it's about to die. Add that character of code in onPause method of your Android Activity/Fragment.
Then in your Server, just get the String or byte and compare it against your Delimiter String/Character and stop the Server listening for the Connection.
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is here. You aren't checking the result of readLine() for null. If it returns null, the peer has closed the connection and you should do likewise, and exit this loop. You can probably get rid of the isInterrupted() test as well.
Also, if you get any IOException other that a read timeout when reading from a socket, the connection is dead and you must close the socket and exit your loop.
now i'm making socket connection to connect multiple client to one server. everything fine, i make thread in different class. But when i will fill textView with string from thread activity, i can't. please help
this MainActivity:
public class MainActivity extends Activity {
private static int port = 6000;
TextView txt;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txt = (TextView) findViewById(R.id.txtCommand);
txt.setText("Server : ");
ServerSocket server1 = null;
Server gameServer = new Server();
try {
server1 = new ServerSocket(port);
// .. server setting should be done here
} catch (IOException e) {
System.out.println("Could not start server!");
// return ;
}
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Server {
private ExecutorService executor = Executors.newCachedThreadPool();
public void handleConnection(Socket client) throws IOException {
PlayerConnection newPlayer = new PlayerConnection(this, client);
txt.setText(newPlayer.getuname());
this.executor.execute(newPlayer);
}
// add methods to handle requests from PlayerConnection
}
and this thread adctivity :
public class PlayerConnection implements Runnable {
private Server parent;
private Socket socket;
private PrintWriter out;
private BufferedReader in;
String line;
protected PlayerConnection(Server parent, Socket socket) throws IOException {
this.parent = parent;
this.socket = socket;
this.in = new BufferedReader(new InputStreamReader(socket
.getInputStream()));
this.out = new PrintWriter(new OutputStreamWriter(
socket.getOutputStream()));
}
public void run() {
while(!this.socket.isClosed()) {
try {
//int nextEvent = this.in.readInt();
line = in.readLine();
System.out.println("Server Receive : "
+ line);
out.println("Server Sent :" +line);
System.out.println("SEND : "
+ line);
out.flush();
if (line == null){
this.socket.isClosed();
break;
}
} catch (IOException e) {}
}
I realized that you have a while loop that never ends in your onCreate method. try to move that loop in to your thread. this loop blocks inputs of your application.
while (true) {
Socket client = null;
try {
client = server1.accept();
gameServer.handleConnection(client);
} catch (IOException e) {
e.printStackTrace();
}
you can use handler or runOnUiThread method.