I made a super simple server on my Windows Machine that waits for a client, and when connected, all it does is get a message and prints it to the Console.
When I run a Server code on my computer, and then run another Client application, it works fine. However, when I run the exact same client code(except for a few changes that are necessary) on my Android Phone(connected via USB), it doesn't work.
The IP address for my PC is correct and the port is free, I've been getting this error message:
W/System.err: java.net.ConnectException: failed to connect to /192.168.10.104 (port 1755) from /:: (port 42102): connect failed: ETIMEDOUT (Connection timed out)
My server.java that runs on my PC is
import java.net.*;
import java.io.*;
public class Server {
// Initialize everything
private Socket socket = null;
private ServerSocket server = null;
private DataInputStream in =null;
//constructor with port
public Server(int port) {
try {
server = new ServerSocket(port);
System.out.println("Server started, waiting for Client...");
socket = server.accept();
System.out.println("Client accepted");
in =new DataInputStream(new BufferedInputStream(socket.getInputStream()));
String line = "";
while (!line.equals("Over")) {
try {
line = in.readUTF();
System.out.println(line);
}
catch(IOException e) {
System.out.println(e);
}
}
System.out.println("Closing connection");
//CLosing connections
socket.close(); in .close();
}
catch(IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) {
Server server = new Server(1755);
}
}
This is the client code
import java.io.*;
import java.net.*;
public class MainActivity extends AppCompatActivity {
TextView Message_shower;
EditText text_place;
TextView messageStatus;
Button send_btn;
// Initialize sockets and IO streams
Socket socket = null;
DataOutputStream out = null;
private static final int SERVERPORT = 1755;
private static final String SERVER_IP = "192.168.10.104";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text_place = findViewById(R.id.editText);
messageStatus = findViewById(R.id.messageStatus);
send_btn = findViewById(R.id.send_btn);
// Shows recent sent message
Message_shower = findViewById(R.id.Message_shower);
// Establish a connection
send_btn.setOnClickListener(new View.OnClickListener() {#Override
public void onClick(View view) {
new Sender().execute();
}
});
}
// Close connections
private void onClose() {
try {
if (socket != null) {
out.close();
socket.close();
}
}
catch(IOException e) {
System.out.println(e);
}
}
class Sender extends AsyncTask < Void,
Void,
Integer > {
private Exception e1;
private Exception e2;
String input;
#Override
protected void onPreExecute() {
EditText text_place = findViewById(R.id.editText);
// Takes input from terminal
input = text_place.getText().toString();
Message_shower.setText(input);
System.out.println("Reached here\n");
}
#Override
protected Integer doInBackground(Void...params) {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
// Sends output to the socket
out = new DataOutputStream(socket.getOutputStream());
}
catch(Exception e) {
this.e1 = e;
}
try {
out.writeUTF(input);
} catch(Exception h) {
this.e2 = h;
}
return 1;
}
#Override
protected void onPostExecute(Integer result) {
if (e1 != null) {
e1.printStackTrace();
}
if (e2 != null) {
e2.printStackTrace();
}
TextView txt = findViewById(R.id.messageStatus);
txt.setText("Message Sent");
text_place.setText("");
onClose();
}
}
}
All input is very appreciated, I've tried various ways like turning off the firewall and such but none worked.
Related
I'm trying to write a simple client/server program, where the client is an android app and the server is a Raspberry Pi 4. All I want to do is allow the client to type a message and have the Raspberry Pi display the message on the terminal. However, my app keeps throwing an exception at the out.writeObject(message_text) line in the sendMessage() method.
public class MainActivity extends AppCompatActivity {
private EditText message;
private Button send;
private ObjectOutputStream out;
private Socket socket;
private String raspi_ip = "enter ip here";
private int raspi_portnum = 12345;
Client client;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
message = findViewById(R.id.message_text);
send = findViewById(R.id.send_button);
try{
client = new Client(raspi_ip,raspi_portnum);
client.start();
} catch (Exception e){
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("Error! ").setMessage("Couldn't connect to server.").setNeutralButton("OK", null).create().show();
}
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
client.sendMessage();
}
});
}
private void closeConnection(){
try{
out.close();
socket.close();
} catch (Exception e){
e.printStackTrace();
}
}
#Override
protected void onStop(){
super.onStop();
closeConnection();
}
private class Client extends Thread {
private String ip_address;
private int port_number;
public Client(String ipaddress,int portnum){
this.ip_address = ipaddress;
this.port_number = portnum;
}
#Override
public void run() {
super.run();
connectToServer(ip_address,port_number);
}
public void connectToServer(String ipaddress, int portnum){
try{
socket = new Socket(InetAddress.getByName(ipaddress),portnum);
out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
}catch (Exception e){
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("Error! ").setMessage("Couldn't connect to server.").setNeutralButton("OK", null).create().show();
}
}
public void sendMessage(){
String message_text = message.getText().toString();
try{
out.writeObject(message_text);
out.flush();
} catch (Exception e) {
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("Error! ").setMessage("IO Exception.").setNeutralButton("OK", null).create().show();
}
}
}
}
Here is the server side java program:
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class RaspPiServer {
private ServerSocket server;
public RaspPiServer(){
}
public static void main(String[] args){
RaspPiServer server = new RaspPiServer();
server.runServer();
}
public void runServer(){
try{
server = new ServerSocket(12345,100);
while (true){
new Controller(server.accept()).start();
}
} catch(Exception e){
e.printStackTrace();
}
}
private class Controller extends Thread {
private Socket socket;
private ObjectInputStream input;
private String in;
public Controller(Socket socket){
this.socket = socket;
System.out.println("New client at " + socket.getRemoteSocketAddress());
}
#Override
public void run(){
try{
input = new ObjectInputStream(socket.getInputStream());
while (!(in = (String)input.readObject()).equals("close")){
System.out.println(in);
}
} catch(Exception e){
e.printStackTrace();
} finally {
closeConnection();
System.out.println("Connection with client # " + socket.getRemoteSocketAddress() + " closed");
}
}
private void closeConnection() {
try {
input.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Is there an easy fix here, or am I missing something bigger?
I'm trying to send commands from my phone to my computer using Sockets.
I've tryed the answers here:
Android and PC Socket connection
But after some digging i found out that you need to use a Async task so i tryed this:
Using AsyncTask for android network connection
But for some reason my socket times out. Is there a way to find out why? because from the error i can't tell:
The error from Logcat:
And this is the client code:
public class MainActivity extends AppCompatActivity {
private Socket client;
private PrintWriter printwriter;
private EditText textField;
private Button button;
private String message;
private static final int SERVERPORT = ####;
private static final String SERVER_IP = "########";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textField = (EditText) findViewById(R.id.editText1); // reference to the text field
button = (Button) findViewById(R.id.button1); // reference to the send button
}
public void onClick(View view) {
message = textField.getText().toString();
textField.setText(""); // Reset the text field to blank
new AsyncAction().execute();
}
private class AsyncAction extends AsyncTask<String, Void, String> {
protected String doInBackground(String... args) {
try {
System.out.println("background running");
System.out.println(message);
client = new Socket(SERVER_IP, SERVERPORT); // connect to server
System.out.println(client.isConnected());
System.out.println("test");
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(message); // write the message to output stream
printwriter.flush();
printwriter.close();
client.close(); // closing the connection
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
I wrote a Server for this in Java and tested it in the emulator.
I had two things to do :
The server IP is "10.0.2.2" if you are using an Android Emulator. LocalHost is de Emulator Virtual Machine.
Your application needs Permission Internet in manifest
Here is the server Code
/**
*
* #author Jean-Pierre
*/
public class SocketServer {
private static final int portnumber = 4444;
public static void main(String[] args) {
SocketServer socketServer = new SocketServer();
socketServer.run();
}
/**
* Reads a String from the client
* Converts it to Uppercase
* and sends it Back.
*/
private void run() {
try {
ServerSocket serverSocket = new ServerSocket(portnumber);
Socket clientSocket = serverSocket.accept();
System.out.println("connected with :" + clientSocket.getInetAddress());
PrintWriter out =
new PrintWriter(clientSocket.getOutputStream(), true);
InputStreamReader is =
new InputStreamReader(clientSocket.getInputStream());
BufferedReader in =
new BufferedReader(is);
while (true) {
String line = in.readLine();
if (line != null) {
System.out.println("recieved:" + line);
out.println(line.toUpperCase());
}
}
} catch (IOException ex) {
Logger.getLogger(SocketServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
I tried to write a simple server for an app that user can write a message from PC using telnet to IP and port. IT works just fine and it can show the
The problem is, when user closes telnet window (CMD window in PC, there is where user connects to app) the app stops.
Is there a way to prevent this behaviour? Here is my code:
//Defined in Activity class
//Sockets, servers, clients and stuff
public java.net.ServerSocket MyServerSocket;
public String IpAddress = "";
public int Port = 12345;
public Handler UpdateConversationHandler;
public Thread ServerThread = null;
Nested classes inside the Activity class:
class ServerThread implements Runnable{
public final String IpAddress;
public final int Port;
public ServerThread(String ipAddress, int port)
{
IpAddress = ipAddress;
Port = port;
}
public void run() {
Socket socket = null;
try{
MyServerSocket = new ServerSocket(Port);
} catch (IOException e) {
e.printStackTrace();
}
while(!Thread.currentThread().isInterrupted()){
try{
socket = MyServerSocket.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() {
_textview_info.setText("Client Says: "+ msg );
}
}
I also have this code for onStop method, but it doesn't help!
#Override
protected void onStop() {
super.onStop();
//Closing server socket
try
{
MyServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
And this is the onCreate method, where the server starts:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_context = this;
//Prepare spinners
_preferences = getSharedPreferences("org.pervasivesystems.nexusmosaic", MODE_PRIVATE);
_preferencesEditor = _preferences.edit();
_spinner_videos = (Spinner) findViewById(R.id.spinner_select_video);
_spinner_ids = (Spinner) findViewById(R.id.spinner_select_id);
populateSpinners();
//Prepare server
IpAddress = getIpAddress();
TextView tvIpAddress = (TextView) findViewById(R.id.textview_ip_address_value);
tvIpAddress.setText(IpAddress);
_textview_info = (TextView) findViewById(R.id.textview_information);
UpdateConversationHandler = new Handler();
ServerThread = new Thread(new ServerThread(IpAddress, Port));
this.ServerThread.start();
}
UPDATE
When I start the app, even before connecting from PC to app using telnet, I get the following message continuesly in LOGCAT:
11-14 15:45:32.460 W/System.err? at java.lang.Thread.run(Thread.java:856)
11-14 15:45:32.460 W/System.err? java.net.SocketException: Socket is closed
11-14 15:45:32.460 W/System.err? at java.net.ServerSocket.checkOpen(ServerSocket.java:362)
11-14 15:45:32.460 W/System.err? at java.net.ServerSocket.accept(ServerSocket.java:120)
11-14 15:45:32.460 W/System.err? at .MainActivity$ServerThread.run(MainActivity.java:233)
Line 233 is refering to this code:
while(!Thread.currentThread().isInterrupted()){
try{
socket = MyServerSocket.accept(); //LINE 233
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
I also found out that after closing the telnet window from PC, the UpdateUiThread keeps running.
What is probably happening is that your communication thread is noticing the terminated connection and exits. This is how you wrote it. Im not sure what you want it to do instead...
If you want to do something after the terminated connection, just put some code right after
while(!Thread.currentThread().isInterrupted()){ ... }
Wait for the thread to finish, then do what you want.
Sometimes it helps me to add some system outs throughout threaded code to get a handle of when things are firing off/ending. It will help, trust me.
Try this
do{
if(!Thread.currentThread().isInterrupted()){
try{
socket = MyServerSocket.accept();
if(socket!=null && socket.isConnected()){
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}while(socket!=null && socket.isConnected());
i got a little problem with my little application by using java Sockets.
if i start my Sockert-Server on pc and i'm connected withmy phone via wifi in the same network by using the (intern) network IP i can send some stuff to my server.
But if i try to send a message via the mobile internet connection,it doesn´t work..there is also no error or something else :/
Here is my android class:
public class Sockets extends Activity {
EditText textOut;
EditText ipAddress;
TextView textIn;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_socket);
textOut = (EditText)findViewById(R.id.textout);
Button buttonSend = (Button)findViewById(R.id.send);
ipAddress = (EditText)findViewById(R.id.ipAddress);
buttonSend.setOnClickListener(buttonSendOnClickListener);
}
Button.OnClickListener buttonSendOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new DatagrammClient(ipAddress.getText().toString(),textOut.getText().toString()).execute("");
textOut.setText("");
}};
private static class DatagrammClient extends android.os.AsyncTask<String, Void, String> {
final static String LOGIN = "LOGIN";
final static String LOGOUT = "LOGOUT";
static int port = 1234;
static int length = 1024; // Länge eines Pakets
static DatagramSocket socket = null;
static InetAddress ia = null;
static DatagramPacket packet;
String hostname = "";
String msg ="";
public DatagrammClient(String hostname,String msg) {
this.hostname = hostname;
this.msg = msg;
}
/**
* Send the login package and open socket
*
* #param servername
* #throws IOException,UnknownHostEception
*/
private static void connectToServer(String servername) throws IOException,UnknownHostException{
packet = null;
byte[] ba = LOGIN.getBytes();
try {
socket = new DatagramSocket();
ia = InetAddress.getByName(servername);
packet = new DatagramPacket(ba, ba.length, ia, port);
Log.d("servername",servername);
Log.d("Internetaddress",ia.toString());
Log.d("SOCKET",socket.toString());
// sende Anmeldung
socket.send(packet);
} catch (SocketException se) {
Log.d("SocketException",se.toString());
}
catch (UnknownHostException he) {
Log.d("UnknownHost: ",he.toString());
}
catch (IOException e) {
Log.d("IOException: ",e.toString());
}
}
public static void sendMessage(String message, String hostname) throws UnknownHostException, IOException{
//if (socket == null){
DatagrammClient.connectToServer(hostname);
//}
DatagrammClient.sendMessageToServer(message);
DatagrammClient.readMessageFromServer();
//Close connection -> Send logout Package?
}
private static void readMessageFromServer(){
// Lesen der empfangenen Pakete erfolgt in eigenem Thread
LeseThread lt = new LeseThread( socket );
}
private static void sendMessageToServer(String message){
byte[] ba = null;
try {
if (!message.equals(LOGOUT)) {
// message = br.readLine();
ba = message.getBytes();
packet.setData(ba, 0, ba.length);
socket.send(packet);
Log.d("Message:",packet.toString());
} else {
ba = LOGOUT.getBytes();
packet.setData(ba, 0, ba.length);
socket.send(packet);
// Exit the system -> do we need to close the socket clientside?
//socket.close();
System.exit(0);
}
} catch (IOException e) {
System.err.println("Ausnahmefehler: " + e);
Log.d("IOEXCEPTION_MESSAGE_TO_SERVER:",e.toString());
}
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try {
DatagrammClient.sendMessage(msg, hostname);
}
catch(Exception e){
Log.d("Error: ",e.toString());
}
return null;
}
}
}
The permission to use the INTERNET is set in the Manifest..
I've tried out almost everything.
Forwarding from ADB Shell using adb forward TCP:12345 TCP:12345
Using 10.0.2.2 (without forwarding) to listen to my host machine
Setting the INTERNET permission in the manifest
Setting the thread policy to permit all functions
I'm running my client java program in 12345 port and I have a ServerSocket in the Android program that listens over the same port. But when I run my client (after running the server program on the emulator) and enter the String that I want to transfer, I get the exception saying 'Connection Refused'.
java.net.ConnectException: Connection refused: connect
Here's my server program:
public class MainActivity extends Activity {
TextView tv;
ServerSocket ss = null;
String mClientMsg = "";
Thread myCommsThread = null;
public static final int SERVERPORT = 12345;
protected static final int MSG_ID = 0x1337;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = new TextView(this);
tv.setText("Nothing from client yet");
setContentView(tv);
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);
setContentView(tv);
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();
}
}
}
}
}
}
My Java client program is as follows:
public class TCPSender {
public static void main(String args[]) {
try {
DataInputStream dis = new DataInputStream(System.in);
System.out.println("Enter the file name:");
#SuppressWarnings("deprecation")
String f = dis.readLine();
File f1 = new File(f);
FileReader fr = new FileReader(f1);
Socket s = new Socket("127.0.0.1", 12345);
PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
pw.println(f);
int c = 0;
while ((c = fr.read()) != -1)
pw.println(c);
System.out.println("File content are sent....");
fr.close();
s.close();
} catch (Exception e) {
System.out.println("" + e);
}
}
}