Android TCP socket client/server implementation - java

I'm new to Java and Android, I'm trying to create a server/client application. For the moment I'm running the server on the PC and the client is on an Android device. The communication takes place and all works fine, but I want to differentiate incoming messages from the client in order to do different actions on the server. Here's the code for the server. The client is pretty easy and works well. For example when I send "Name" from the client, the serve should answer with "Matteo" but it always answers with "Something else" and I can't understand why! I imagine that the problem is in the statement if (dataInputStream.equals("Name")) {
Thank you.
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server1 {
public static void main(String[] args){
ServerSocket serverSocket = null;
Socket socket = null;
DataInputStream dataInputStream = null;
DataOutputStream dataOutputStream = null;
try {
serverSocket = new ServerSocket(8888);
System.out.println("Listening on port 8888");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true){
try {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
System.out.println(socket.getInetAddress() + " : " + dataInputStream.readUTF());
if (dataInputStream.equals("Name")) {
dataOutputStream.writeUTF("Matteo!");
}
else if (dataInputStream.equals("Surname")) {
dataOutputStream.writeUTF("Rossi!");
}
else {
dataOutputStream.writeUTF("Something else!");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if( socket!= null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if( dataInputStream!= null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if( dataOutputStream!= null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}

DataInputStream represents the handle to stream of data coming from the socket, but not the data itself. So .equals() compares it with another DataInputStream not with a String. You are comparing it directly with a string, which obviously returns false.
Just like you are writing data with writeUTF(), you need to read data from the socket connection through that DataInputStream. Use one of the read() methods described here or if you know that your client will send whole lines, you can wrap it in a BufferedReader and use the following:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
String input = bufferedReader.readLine();
if (input.equals("Name")
{
dataOutputStream.writeUTF("Matteo!");
}
else ...
On another note, in Java 7, you can use switch statements on String too, instead of .equals()

The trick is that you should read something from the DataInputStream. Eg.
byte[] buffer = new byte[ 1024 ];
dataInputStream.read( buffer );
if ( new String( buffer ).equals( "Name" ) ) { /* do your stuff */ }
This is much abbreviated, but you could work from there.
Cheers,

Maybe look into an ObjectInputStream you can then read the object and use the:
instanceof
keyword to differntiate between objects

Related

android client side doesnt read after a while

It's my first question in here. I hope i can find answer. Subject is that, i have server (arduino). it send and receive data.it send data when take a data from client side(android). Android side is send data when push button. Also android has use Speech to Text (google API).So when we push button or use speechrecognation, client side send a data.But it reads socket continuously. I have two kind android device. One device work well about data receiving but it is not good about speechrecognation. One device very well about voice but after a while socket is happened useless. We must push reset button on arduino and reset android app. (My first android device version is 5.1.1 second is 6.0). Sorry for my english. I hope i can tell my problem :)
.
.
.
public void senddata(String asd){
try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(asd);
out.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
.
.
.
class ClientThread implements Runnable {
#Override
public void run() {
BufferedReader inStream = null;
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
//socket.setSoTimeout(1000);
// Get the input and output streams
inStream = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
// Confirm that the socket opened
// Read messages in a loop until disconnected
while( true){
String msg= inStream.readLine();
Log.e("GELENLER::::",msg);
gelenkomut=msg;
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
gelenparse(gelenkomut);
}
});
// Send it to the UI thread
}
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
finally {
try {
inStream.reset();
inStream.
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Program stop working when try to read input stream

I have a Java Server and one(or more) Android Clients. For now I want them to communicate simply with strings. When i write from android I can get the data in Java Server, but when I try to get the answer from server the Android application stop working. The codes is reported below:
Java Server:
public class Server {
private static int port=12346, maxConnections=0;
// Listen for incoming connections and handle them
public static void main(String[] args) {
int i=0;
try{
ServerSocket listener = new ServerSocket(port);
Socket server;
while((i++ < maxConnections) || (maxConnections == 0)){
doComms connection;
server = listener.accept();
String end = server.getInetAddress().toString();
System.out.println("\n"+end+"\n");
doComms conn_c= new doComms(server);
Thread t = new Thread(conn_c);
t.start();
}
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
}
class doComms implements Runnable {
private Socket server;
private String line,input;
public doComms(Socket server) {
this.server=server;
}
#SuppressWarnings("deprecation")
public void run () {
input="";
try {
// Get input from the client
DataInputStream in = new DataInputStream (server.getInputStream());
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(server.getOutputStream())),
true);
while((line = in.readLine()) != null && !line.equals(".")) {
input=input + line;
}
JOptionPane.showMessageDialog(null, input);
out.println("Enviado");
server.close();
} catch (IOException ioe) {
System.out.println("IOException on socket listen: " + ioe);
ioe.printStackTrace();
}
}
And Android client's code (it's called every time a button is pressed inside onClick method):
public String enviaMensagem(){
String resposta="";
new Thread(new ClientThread()).start();
Socket socket = null;
DataOutputStream dataOutputStream = null;
DataInputStream dataInputStream = null;
try {
socket = new Socket(ip, port);
dataOutputStream = new DataOutputStream(socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream.writeUTF(input.getText().toString());
resposta = dataInputStream.readUTF();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataOutputStream != null){
try {
dataOutputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dataInputStream != null){
try {
dataInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return resposta;
}
You are using an unsorted mixture of readUTF(), writeUTF(), readLine(), etc. They're not all interoperable. Settle on one of them. If you use writeUTF() you must use readUTF() at the other end. If you use readLine() you must write lines at the other end, with a line terminator such as \r\n or \n.

Where and when should I use the close() method to avoid IOException in ObjectInputStream?

I'm trying to read an object from client program over tcp. As you can see in this line I created objectInput:
ObjectInputStream objectInput = new ObjectInputStream(incoming.getInputStream());
And then read my input from the other program. It used to work fine until i made minor changes to clean up the program. Personally Assume I added
objectInput.clsoe();
My question is, After reading the object should I close the objectInputStream or Keep remain without close? Should I close it straight away after using it or at the end of if block or at the end of program? What are the effect of the close? By the way I have read the close documentation.
Here is the error:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2280)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2749)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:779)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
at Server.ClientWorker.run(MyCollectionServer.java:116)
at java.lang.Thread.run(Thread.java:680)
Here is my code:
public static void main(String[] args) {
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(port);
}
catch (IOException e)
{
e.printStackTrace();
}
while(true)
{
ClientWorker w;
try
{
w = new ClientWorker(serverSocket.accept());
Thread t = new Thread(w);
t.start();
}
catch(IOException e)
{
e.printStackTrace();
break;
}
}
}
}
class ClientWorker implements Runnable
{
.....
private Socket incoming;
public ClientWorker(Socket incoming)
{
myList = new ArrayList<PureAlbum>();
loadList();
this.incoming = incoming;
}
.....
public synchronized void run()
{
else if(request.compareTo("AddAlbum")==0)
{
try
{
ObjectInputStream objectInput = new ObjectInputStream(incoming.getInputStream()); //This is the line mentioned in the error
PureAlbum object = (PureAlbum) objectInput.readObject();
if(object instanceof CDAlbum)
{
CDAlbum a = (CDAlbum) object;
myList.add(a);
System.out.println("Artist = " + a.getArtist());
}
else if(object instanceof Client.au.edu.uow.Collection.DVDAlbum)
{
myList.add((DVDAlbum) object);
}
else
{
System.err.println("Warning : The object to add to database is unknown! "+ object.getClass() + "*");
System.exit(0);
}
}
catch (UnknownHostException e)
{
System.err.println("Can not read the host name");
e.printStackTrace();
}
catch (IOException e)
{
System.err.println("Can not read the FILE name"); //This exception has been called
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
Your code fragment is pretty long, so I will try to give you a general answer and it will hopefully help you.
The typical patterns of usage of stream.close() prior to java 7 are:
InputStream in = null;
try {
InputStream in = .....; // create your input stream;
// use input stream
} catch (IOException e) {
// do what you need here
} finally {
if (in != null) {
in.close();
}
}
or simply declare the method as throws IOException and then write:
InputStream in = null;
try {
InputStream in = .....; // create your input stream;
// use input stream
} finally {
if (in != null) {
in.close();
}
}
Pay atention that this example does not contain catch section.
Starting from java 7 we can enjoy the new facilities of the language:
try (
InputStream in = .....; // create your input stream;
) {
// use input stream
}
You even do not have to call close() at all. All resources defined into header of try block that implement interface Closable will be closed automatically.
This line of stack trace shows that the exception is occurring when you are initializing the ObjectInputStream, not when you are closing.
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
The most likely cause is that the remote client did not open an ObjectOutputStream. It might have written some other kind of data, or it might have closed its output stream or simply exited.
You should close the Stream when you have completed your reading or writing.
here in this case , you should close the InputStream when you have read the file completely and you no longer require to read file from stream.
In Short , You should close the Stream when its work is over.
It may be in the end of program or after if loop....depends on your use case.
Hope this will help.
I am doing it this way (different example):
private void readFile() throws Exception {
FileInputStream fis = null;
ObjectInputStream ois = null;
Object aux = null;
try {
fis = new FileInputStream("lib.dat");
ois = new ObjectInputStream(fis);
do {
aux = ois.readObject();
if (aux instanceof MyObject)
this.myObjectInstance.add((MyObject) aux);
} while (true);
} catch (EOFException e) {
ois.close();
}
}
This way I am sending any relevant "Error" Exception upstairs to be handled, and once the EndOfFileException is launched this is specifically captured to close the stream properly.
The object has to be defined outside the Try block to be accessible from the Catch block.
The close() method could as well throw an IOException and this can't be caught by our Try block, this would have to be passed by the generic "throw Exception" of readFile() method.

How to identify if ObjectInputStream has available object?

Getting error NullPointerException while trying to identify if serialized object is available and receive it using socket. How to identify if ObjectInputStream has available object?
Firs off I try to read a text then try to read from the same socket Lot object ()which may not be there.
public class ThreadIn extends Thread{
BufferedReader in;
PrintStream outConsole;
Socket socket;
ObjectInputStream ois;
String str;
Lot lot;
ThreadIn(BufferedReader input, PrintStream inOutput, Socket s){
str = "";
in= input;
socket= s;
try {
ois = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
outConsole = inOutput;
}
public void run() {
while(!EXIT_THREAD){
try {
if(in.ready()){
try {
str= in.readLine();
Thread.sleep(100);
} catch (IOException e) {
EXIT_THREAD= true;
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
outConsole.println("Received:"+str);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if((Lot)ois.readObject() != null){
lot = (Lot)ois.readObject();
if (lot!=null){outConsole.println(lot.toString());}
outConsole.println((String)ois.readObject());
}
} catch (Exception e) {
e.printStackTrace();
}
}
if((Lot)ois.readObject() != null)
this part itself reads the object from Socket., So you are reading 3 times the object from Socket in your code. If you have only one Object coming in the socket, or more, you can read the object and catch the exception!.
Just like below
//..loop start
try {
lot = (Lot)ois.readObject();
}
catch (Exception e)
{
// do some handling, skip the object! put a continue: or something
}
//do what ever you want to do with `lot`
//..loop end
and now, as per your code, you have not initialized your ObjectInputStream Object.
Do a ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
If you omitted the code here, well my mistake, else pls do initialize the socket also!
As per the other answers, including the deleted ones, you are calling readObject() twice and throwing the first result away. You should reorganize your code so it can block in readObject().
You have other problems. You are testing the result of readObject() for null?, but it only returns null if you wrote a null at the sender. I suspect you are using this as an EOS test, but it is invalid. readObject() throws EOFException at EOS. You should reorganize your code so it can block in readObject().

creating socket connection

I need to create a socket connection between my machine and a server. Then I need to send some sms to server from my mechine using smpp protocol. Now I am not being able to create the socket connection. Can any body help me by giving some code to create the socket connection.
My code is:
import java.io.IOException;
import java.net.Socket;
import com.logica.smpp.TCPIPConnection;
public class SocketConnection {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SocketConnection tl= new SocketConnection();
tl.connect();
}
public void connect()
{
TCPIPConnection tc = new TCPIPConnection("172.16.7.92", 9410);
try {
tc.accept();
System.out.println("connected");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
this code is not working.
Thanks,
koushik
If you are trying to connect outwards to a server (rather than listen for incoming connections), then you shouldn't be calling accept.
Here's a simple example how to open a plain socket (to www.google.com, on port 80/HTTP) and use it to send and read data:
try {
Socket socket = new Socket("www.google.com", 80);
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer.println("GET /");
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
For your case there seems to be an open() method for the TCPIPConnection. Probably you should use that instead of accept().

Categories

Resources