i have watched a tutorial, and with the code of this, my phone phone chrashes every time it trys to send the text.
Client:
textField = (EditText) findViewById(R.id.editText1);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
messsage = textField.getText().toString();
textField.setText("");
try {
client = new Socket(InetAddress.getByName("jarves-server.no-ip.info"), 8000);
printwriter = new PrintWriter(client.getOutputStream(),true);
printwriter.write(messsage);
printwriter.flush();
printwriter.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
Server:
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(8000);
} catch (IOException e) {
System.out.println("Could not listen on port");
}
System.out.println("Server started.");
while (true) {
try {
clientSocket = serverSocket.accept();
inputStreamReader = new InputStreamReader(clientSocket.getInputStream());
bufferedReader = new BufferedReader(inputStreamReader);
message = bufferedReader.readLine();
System.out.println(message);
inputStreamReader.close();
clientSocket.close();
} catch (IOException ex) {
}
}
}
I really don`t know what is wrong with the code. Maybe it could be also the DynDns i have set up with No-IP and our Speedport W723V and a Port forwarding on Port 8000 to my PC where the Server is running.
Hope for help!
If you had looked in the LogCat you would have seen a NetworkOnMainThreadException. You have to place your socket code in an AsyncTask or Thread.
Related
I am trying to connect an Android device to a java server. It works perfectly when I use the emulator but when I port it onto my phone there is no connection.
The aim of the code is to send a value from client to server, perform a calculation on it and return it back to the client to be displayed.
This is my server code:
public class ServerTest {
public static final int PORT_NUMBER = 8000;
protected Socket socket;
private ServerTest(Socket socket) {
this.socket = socket;
System.out.println("New client connected from " + socket.getInetAddress().getHostAddress());
connect();
}
public void connect() {
InputStream in = null;
OutputStream out = null;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String request = br.readLine();
if (request.equals("end")) {
System.out.println("Message received: " + request + ". Ending connection.");
request = "End Connection";
out.write(request.getBytes());
in.close();
out.close();
socket.close();
System.exit(0);
} else {
System.out.println("Message received: " + request);
request = calculatePi(request);
System.out.println("Output: " + request);
out.write(request.getBytes());
}
} catch (IOException ex) {
System.out.println("Unable to get streams from client");
} finally {
try {
in.close();
out.close();
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public static void main(String[] args) {
System.out.println("Welcome. IP address is: " + getIP());
ServerSocket server = null;
try {
server = new ServerSocket(PORT_NUMBER);
while (true) {
new ServerTest(server.accept());
}
} catch (IOException ex) {
System.out.println("Unable to start server.");
} finally {
try {
if (server != null)
server.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static String getIP() {
String ip = "";
try {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
// filters out 127.0.0.1 and inactive interfaces
if (iface.isLoopback() || !iface.isUp())
continue;
Enumeration<InetAddress> addresses = iface.getInetAddresses();
while(addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
// *EDIT*
if (addr instanceof Inet6Address) continue;
ip = addr.getHostAddress();
}
}
} catch (SocketException e) {
throw new RuntimeException(e);
}
return ip;
}
and this is my client side code on device:
public class MainActivity extends AppCompatActivity {
TextView piResultTextView;
EditText addressEditText, messageEditText;
Button connectButton;
Handler handler = new Handler();
Results results;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
results = new Results();
addressEditText = findViewById(R.id.AddressEditText);
messageEditText = findViewById(R.id.MessageEditText);
connectButton = findViewById(R.id.ConnectButton);
connectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
connect();
}
});
piResultTextView = findViewById(R.id.PiResultTextView);
}
public void connect() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
String hostAddress = addressEditText.getText().toString();
int port = 8000;
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
try {
echoSocket = new Socket(hostAddress, port);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
Toast.makeText(getApplicationContext(), "Unknown host: " + hostAddress, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Unable to get streams from server", Toast.LENGTH_SHORT).show();
}
String input = messageEditText.getText().toString();
try {
out.println(input);
results.pi = in.readLine();
handler.post(new Runnable() {
#Override
public void run() {
piResultTextView.setText(results.pi);
}
});
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Unable to read input stream from server", Toast.LENGTH_SHORT).show();
}
try {
out.close();
in.close();
echoSocket.close();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "Error closing streams", Toast.LENGTH_SHORT).show();
}
}
});
thread.start();
}
}
I have established a connection between java server and android client using sockets. I can send messages from android to java, but only 1 message at a time.
what if I want to send data of 2 variables from android to java and at the same time receive those data in java in 2 different variables.
How can I achieve this.??
Code for Android Client
public class MessageClient extends Activity implements OnClickListener {
EditText etMessage;
Button bSend;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messageclient);
bSend = (Button) findViewById(R.id.button1);
etMessage = (EditText) findViewById(R.id.etMessage);
bSend.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
try {
Socket s = new Socket("192.168.0.100",7000);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
dos.writeUTF(etMessage.getText().toString());
dos.flush();
dos.close();
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Code for java server
public static void main(String arg[]){
Thread t = new Thread(){
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket ss = new ServerSocket(7000);
while(true){
Socket s = ss.accept();
System.out.println("Server is running");
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println("Received from client: "+dis.readUTF());
dis.close();
s.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
}
Thank you.
You are just sending a String and then closing the socket.You can try to send lists and also can send multiple DataInputStream dis without closing the socket connection.
I create a simple network-testing application.
But It doesn't work and always throw error at Socket().
I tried to check error message by using getMessage(), there was no message printed.
What should I do?
public static void main(String args[]){
ServerSocket serverSocket = null;
Socket socket = null;
try{
serverSocket = new ServerSocket(14100);
socket = serverSocket.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
byte[] arr = new byte[100];
in.read(arr);
System.out.println(new String(arr));
String str = "Hello Client";
out.write(str.getBytes());
}
catch(Exception e){
System.out.println(e.getMessage());
}
finally{
try{
socket.close();
}
catch(Exception ignored){}
try{
serverSocket.close();
}
catch(Exception ignored){}
}
}
Below is android code for Client.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
TextView tv = (TextView) findViewById(R.id.id_tv);
Socket socket = null;
try{
socket = new Socket("192.168.0.52",14100);
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
String str = "Hello Server";
out.write(str.getBytes());
byte arr[] = new byte[100];
in.read(arr);
tv.setText(new String(arr));
}
catch(UnknownHostException uhe){
}
catch(IOException ioe){
}
catch(Exception e){
}
finally{
try{
socket.close();
}
catch(Exception ignored){
}
}
}
Of course, I added permisson for android in AndroidManifest.xml
Move the socket code out of UI main thread onCreate() to an AsyncTask or a regular thread.
For a quick test, wrap all your socket code into a thread like so:
new Thread() {
public void run() {
// Move your socket code here for a quick test
}
}.start();
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 have got huge problem with my Android app and I would like to ask you for help.
I am currently writing Android Clietn-Server app using sockets. I have found lots of tutorils on the Internet and from them I have created basics for my project. However, all tutorials are only for one message send and that's all. I need to send more of them so I've been trying to modify it.
This are code fragments responsible for server and client. The rest is not important at this time.
Server:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverStatus = (TextView) findViewById(R.id.server_status);
recivedMsg = (TextView)findViewById(R.id.rec_msg);
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);
}
});
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
// listen for incoming clients
Socket client = serverSocket.accept();
handler.post(new Runnable() {
#Override
public void run() {
serverStatus.setText("Connected." + System.getProperty("line.separator"));
}
});
try {
line = null;
while (connected) {
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
if((line = in.readLine())!=null)
{
Log.d("ServerActivity", line);
handler.post(new Runnable() {
#Override
public void run() {
if(recivedMsg.equals("CLOSE"))
{
recivedMsg.append("CLOSE socket");
connected = false;
}
else
{
recivedMsg.append("MSG: " + line + System.getProperty("line.separator"));
}
// do whatever you want to the front end
// this is where you can be creative
}
});
}
else
{
recivedMsg.append("empty" + System.getProperty("line.separator"));
}
}
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();
}
}
}
Client
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
serverIp = (EditText) findViewById(R.id.server_ip);
connectPhones = (Button) findViewById(R.id.connect_phones);
sendField = (EditText) findViewById(R.id.send_field);
sendMsg = (Button) findViewById(R.id.msg_send);
connectPhones.setOnClickListener(connectListener);
sendMsg.setOnClickListener(sendMessage);
}
#Override
protected void onStop() {
super.onStop();
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "CLOSE";
out.write(outMsg);
out.flush();
// make sure you close the socket upon exiting
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private OnClickListener connectListener = new OnClickListener() {
#Override
public void onClick(View v) {
serverIpAddress = serverIp.getText().toString();
runTcpConnection();
sendMessageToServer("Msg");
}
};
private OnClickListener sendMessage = new OnClickListener() {
#Override
public void onClick(View v) {
sendMessageToServer(sendField.getText().toString());
}
};
private void runTcpConnection() {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
SystemClock.sleep(10);
s.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
};
public void sendMessageToServer(String str) {
try {
s = new Socket(serverIpAddress, SERVERPORT);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//send output msg
String outMsg = str + System.getProperty("line.separator");
out.write(outMsg);
out.flush();
Log.i("TcpClient", "sent: " + outMsg);
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello222");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("", "hello4333");
}
}
For now devices connect correctly. Moreover They are sending the first connection messages (those in OnClickListener connectListener). The problem is that when I am trying to send another message using sendMessageToServer it is impossible. Those messages shows only after client activity is destroyed.
Very interesting is that without SystemClock.sleep(10); listener runTcpConnection() behave strange. Only 'Connected.' displays on server.
Can someone tell me what I have to do to be able to send messages normally?
EDIT:
This are things that I have found:
If I am at the connection sending more messages than all are empty (null) and after the second one connection error shows - please reconnect phones
If I am at the connection sending more messages without s.close line in sendMessageToServer only one message is passing through. No error is displayed after it.
The message form runTcpConnection shows always (except when in this function is no SystemClock.sleep(10))
Hope it will help someone to diagnose my error.
As I see, you create a new socket whenever user click button send, right? I recommend you should init it only one time when user click connect, then you use it in send click event ( because this is TCP, you will disconnect to server if you create new instance of socket)
So, you should remove these lines in sendMessageToServer :
s = new Socket(serverIpAddress, SERVERPORT);
s.close();
and this line in runTcpConnection
s.close();
Socket should close whenever you don't want communicate with the server (onstop is an example, or when change activity...)
Also you should create only one instance of BufferedWriter too.
Hope this help.