Communicating over a socket connection: - java

Steps done:
I have the server running looking for connections on socket 4444.
I have the android application connect to the socket.
I have the android application send two parameters across the socket connection.
I have the server digest the two separate parameters and process them accordingly.
My problem begins when I try to send a message back.
Please could you guys help me with an example of a client class and a server class using BufferedReader and PrintWriter to send data from the client to the server, accepting the data on the server side and returning data for the client to receive?
Thanks for you help.

create a new PrintWriter from the socket output stream,
PrintWriter writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
writer.write("blather");
writer.flush();

Dont use reader/writer some times i cause problem such as we cannOt predict end of string,etc.So please write or read only byte or byte array.It is the better way.
The following are the sample coding snippet
socket=new Socket(this.ipAddress,this.port_number);
//socket.setSocketImplFactory(fac)
Log.i(tagName, "after creating sokcet");
os=socket.getOutputStream();
is=socket.getInputStream();
dos=new DataOutputStream(os);
Log.i(tagName, "after creating ouput streams");
dis=new DataInputStream(is);
Log.i(tagName, "after creating input streams");
//dos.writeUTF(msg[i].trim());
//dos.write(msg[i].trim().getBytes());
//dos.writeUTF(msg[i].trim());
dos.write(msg[i].trim().getBytes());
//dos.writeUTF(str)
dos.flush();
Log.i(tagName, "after writing data to os");
StringBuilder sbuilder=new StringBuilder();
///*
int ch;
byte bt=1;
while((bt=(byte) dis.read())!=-1)
{
Log.i(tagName, "ch="+bt);
byte temp[]=new byte[1];
//temp[0]=(byte)ch;
temp[0]=(byte)bt;
String tempStr1=new String(temp);
Log.i(tagName, "tempstr:"+tempStr1);
sbuilder.append(tempStr1);
Log.i(tagName, "Data fro server : "+sbuilder.toString());
tempStr1=null;
}
//*/
//byte tt[]=new byte[dis.readLine()]
//resultStr=dis.readLine();resultStr=resultStr.trim();
resultStr=sbuilder.toString();
Log.i(tagName, "server res :"+resultStr);
(Toast.makeText(this.actitivity,"Result : "+resultStr,Toast.LENGTH_SHORT)).show();
if(dos!=null)
{
try
{
dos.close();
}
catch(Exception ex)
{
}
}
if(dis!=null)
{
try
{
dis.close();
}
catch(Exception ex){}
}
if(socket!=null)
{
try
{
socket.close();
}
catch(Exception ex)
{
}
}

Related

How to communicate between Java and Dart through Socket

I would like to run a combination of Dart and Java code, that can communicate with each other.
Therefore I chose to go with sockets, with the server socket written in Java and the client socket written in Dart.
This is the code I wrote:
Server
ServerSocket server = new ServerSocket(12345);
server.setSoTimeout(0);
System.out.println("waiting for connection...");
while (true) {
try {
Socket client = socket.accept();
DataInputStream input = new DataInputStream(client.getInputStream());
DataOutputStream output = new DataOutputStream(client.getOutputStream());
System.out.println("connected to " + client.getLocalSocketAddress() + ".");
while (true) {
output.write(input.readLine());
}
} catch (IOException e) {
System.out.println("disconnected.\n\nwaiting for connection...");
}
}
Client
Socket client = await Socket.connect('localhost', 12345);
client.write('hello there\n');
client.close();
Unfortunately the server does not receive the ping message sent by the client.
By now I suppose, that the problem lies in the Dart code, because when executing a client written in Java worked just fine.
Do you know, how to solve this? If so, please let me know ho. Thank you in advance!
Please note:
As there will never be more than one client at a time, I chose to go with this approach. I am aware, that normally this is no good style.
In the documentation for close() on the Socket class:
NOTE: Writes to the IOSink may be buffered, and may not be flushed by a call to close(). To flush all buffered writes, call flush() before calling close().
https://api.dart.dev/stable/2.7.1/dart-io/Socket/close.html
I do not know why, but it seems that the problem lies in the DataInputStream/DataOutputStream.
Here is what worked:
Server
ServerSocket server = new ServerSocket(12345);
server.setSoTimeout(0);
System.out.println("waiting for connection...");
while (true) {
try {
Socket client = socket.accept();
BufferedWriter output = BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("connected to " + client.getLocalSocketAddress() + ".");
while (true) {
output.writeUTF(input.readUTF());
}
} catch (IOException e) {
System.out.println("disconnected.\n\nwaiting for connection...");
}
}
Client
Socket client = await Socket.connect('localhost', 12345);
client.write('hello there\n');
client.close();
This is working for me.
Socket client = socket.accept();
byte[] b = new byte[100];
client.getInputStream().read(b);
System.out.println(new String(b));

readLine of socket input stream causes hang in socket

hi I have an application that sends text to a device and the device shows it on a display. for transferring data I'm using socket in a AsyncTask class
try {
Socket socket = new Socket(DISPLAY_IP, DISPLAY_PORT);
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println(params[0]);
output.flush();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
the problem is I can't read response from socket after sending data. when I'm getting input stream from socket and reading line I'm not getting anything and the device is not showing the sent data from me till I close the application so I think the socket is blocking when I'm doing that
try {
Socket socket = new Socket(DISPLAY_IP, DISPLAY_PORT);
OutputStream out = socket.getOutputStream();
PrintWriter output = new PrintWriter(out);
output.println(params[0]);
output.flush();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String response = bufferedReader.readLine();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
how can I send data and read response from socket?
You are trying to communicate with two (client) Sockets. For communication you must implement on one side a (client) java.net.Socket and on the other a java.net.ServerSocket.
You may read further here.
What are you trying to achieve?
When using InputStream it will get data that came from other side, not the data that you just sent.
And as SirGregg said readLine will hang until the whole line is received.

Proper way of closing Streams in Java Sockets

I saw some posts about this but I still can't find an answer.
This is how my server interacts with the client:
public void run () {
try {
//Read client request
InputStream is = server.getInputStream();
byte[] buff = new byte[1024];
int i;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((i = is.read(buff, 0, buff.length)) != -1) {
bos.write(buff, 0, i);
System.out.println(i + " bytes readed ("+bos.size()+")");
}
is.close();
is = null;
//Do something with client request
//write response
OutputStream os = server.getOutputStream();
os.write("server response".getBytes());
os.flush();
os.close();
os = null;
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
And this is the client side:
public void run() {
try {
InetAddress serverAddr = null;
serverAddr = InetAddress.getByName("10.0.2.2");
socket = new Socket(serverAddr, 5000);
//Send Request to the server
OutputStream os = socket.getOutputStream();
os.write(jsonRequest.toString().getBytes("UTF-8"));
os.flush();
os.close();
os = null;
//Read Server Response
InputStream is = socket.getInputStream();
byte[] buff = new byte[1024];
int i;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while ((i = is.read(buff, 0, buff.length)) != -1) {
bos.write(buff, 0, i);
System.out.println(i + " bytes readed ("+bos.size()+")");
}
is.close();
is = null;
//Do something with server response
} catch (UnknownHostException uhe) {
sendCallbackError(uhe);
} catch (IOException ioe) {
sendCallbackError(ioe);
}
}
As you can see, the client connects and send a request. Server read that request then writes a response that the client will read.
The problem with this code is the OutputStream.close() in the client and InputStream.close() in the server. As stated in the Javadocs, closing the stream will close the Socket. The result is that when the client tries to read the server response, the Socket is already closed.
I've managed to overcome this by calling Socket.shutdownInput and Socket.shutdownOutput instead. However I am still thinking whether this is the proper way of doing it
As a note, closing the streams with close() when server writes the response or when the client reads it doesn't create problems (I would guess the closing is synchronized between client and server).
So my questions are:
Is using the Socket shutdown methods a proper way?
Can I keep closing the last streams with close() (when sending and reading
response from server)
Could it happen that closing with shutdown would keep some data in
the buffer and wouldn't be sent?
You can do the following:
try{
}catch(){
}finally{
if(is!=null){
is.close();
}
if(os!=null){
os.close();
}
}
The problem with this code is the OutputStream.close() in the client and InputStream.close() in the server. As stated in the Javadocs, closing the stream will close the Socket.
Correct but the InputStream in the server isn't connected directly to a Socket: it is connected to something you don't know anything about. You can close it with impunity, although again you don't need to close it at all. You can close the OutputStream in the server if you like: although, again, as it isn't connected directly to a Socket, it may or may not have any effect other than flushing.
To address your actual question, you don't need to close the output stream in the client, but you do need to send an appropriate Content-Length: header. That way the server knows how much to read from the client. If this is only a GET request the content-length may well be zero. You don't need to call shutdownOutput(), although I guess there is nothing to stop you, and calling shutdownInput() doesn't do anything to the network anyway so again there is no point to it.

Client application socket closed after printing string

I'm building a Java client application which needs to send a message to a server and receive a response afterwards. I can send the message successfully, the problem is that I can't get the response because I get an IO exception ("Socked is closed") when trying to read the 'BufferedReader'.
This is my code, so far:
public class MyClass {
/**
* #param args the command line arguments
*/
#SuppressWarnings("empty-statement")
public static void main(String[] args) {
JSONObject j = new JSONObject();
try {
j.put("comando", 1);
j.put("versao", 1);
j.put("senha", "c4ca4238a0b923820dcc509a6f75849b");
j.put("usuario", "1");
j.put("deviceId", "1");
} catch (JSONException ex) {
System.out.println("JSON Exception reached");
}
String LoginString = "{comando':1,'versao':1,'senha':'c4ca4238a0b923820dcc509a6f75849b','usuario':'1','deviceId':'1'}";
try {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("10.1.1.12", 3333);
System.out.println("Connected to the server successfully");
PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(),true);
outToServer.println(j.toString());
outToServer.close();
System.out.println("TO SERVER: " + j.toString());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String resposta = inFromServer.readLine();
System.out.println("FROM SERVER: " + resposta);
clientSocket.close();
} catch (UnknownHostException ex) {
System.out.println("Could not connect to the server [Unknown exception]");
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
I know that the socket is being closed because of the OutToServer.close() but closing the stream is the only way to send the message. How should I approach this situation?
flush() is not the case when it comes with new PrintWriter(, true).
The real problem is that you are closing the PrintWriter outToServer which wraps the underlying InputStream, again, came from the Socket.
When you close the outToServer you're closing the whole socket.
You have to use Socket#shutdownOutput().
You don't even have to close the output if you want to keep the socket's in/out channels for further communications.
flush() when you are done with any writeXXX. Those writeXXX practically don't mean you sent those bytes and characters to other side of the socket.
You may have to close the output, and output only, to signal the server that you sent all you had to send. This is really a matter of the server-side socket's desire.
final Socket socket = new Socket(...);
try {
final PrintStream out = new PrintStream(socket.getOutputStream());
// write here
out.flush(); // this is important.
socket.shutdownOutput(); // half closing
// socket is still alive
// read input here
} finally {
socket.close();
}
Try to call outToServer.flush()
That will try to flush the data from the buffer, although it still not guarantees that it will be sent.

Problem with Chat client program

I have a server chat and client chat programs running on localhost. When I try to connect to the server my client program freezes on next line in = new ObjectInputStream(socket.getInputStream());
here is a piece of code where I try to connect to the server
Socket socket = new Socket(host, port);
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
Message m = new Message(null, nick, Message.Type.REGISTER);
out.writeObject(m);
out.flush();
} catch (IOException ex) {
socket.close();
throw ex;
}
Message class implements Serializable interface, so it can be serialized over the network. And here is a piece of code where server hadle client request
try {
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(client.getInputStream()));
Message m = (Message) in.readObject();
switch (m.getMessageType()) {
case REGISTER:
registerUser(m);
break;
case CHATMESSAGE:
sendMessageToAll(m);
break;
case UNREGISTER:
unregisterUser(m);
break;
}
} catch (ClassNotFoundException ex) {
Logger.getLogger(Chatserver.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Chatserver.class.getName()).log(Level.SEVERE, null, ex);
}
methods registerUser, unregisterUser, sendMessageToAll simply call next method
private void sendMessage(Message m, Socket s) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(s.getOutputStream()));
out.writeObject(m);
out.flush();
// out.close();
}
Where is a mistake?
It seems like the problem might be the same as the one described here.
Just faced this problem .. So giving the answer in this thread itself :
ObjectOutputStream writes a stream header when we create it (new ObjectOutputStream(out))
Similarly , ObjectInputStream , when we create it (new ObjectInputStream(in)) , tries to read the same header from the corresponding ObjectOutputStream at the server side
Here , in client ,
in = new ObjectInputStream(socket.getInputStream());
the ObjectInputStream created blocks when trying to read the stream header , which will not come since there is no corresponding ObjectOutputStream at server which will write the header to the client .
The problem is not just this . If the ObjectOutputStream creation at one side aligns with some other reads at the client side which is supposed to read something of our choice , it may read the stream header instead of the actual value and end up in an incorrect value .
Solution :
The ObjectOutputStream and the ObjectInputStream created at the client and server sides must align with each other .

Categories