Can't use InputStream from Socket after writeObject - java

Here is the situation:
I have a ServerSocket ss, and "Socket socket = ss.accept();", then if I do this:
istream = socket.getInputStream();
ostream = socket.getOutputStream();
in = new BufferedReader(new InputStreamReader(istream));
out = new PrintWriter(new BufferedOutputStream(ostream));
/*
I use in/out few times
everything OK
*/
ObjectOutputStream oos = new ObjectOutputStream(ostream);
oos.writeObject(someobject);
/* probably code that solves the problem */
String line = in.readLine();
On the client side I have this code:
PrintWriter out = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()),true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
/*
using in/out, no problems
*/
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
SomeObject so = (SomeObject)ois.readObject();
out.println("some text");
Everything is OK, until I send someobject. Client recieves object properly, no problems there. But I can't use socket anymore. If I do oos.close(), I get Exception that says "socket closed". If I do oos.reset() I get Exception with similar message. "socket reset". So what should I do? Is it possible to use same input and output streams after writeObject()?
What happens when I send "some text" is that I'm just getting nulls no matter how many times I call readLine(), I never get that "some text".

You can't use multiple type of stream/reader/writer on the same underlying socket. All your streams and readers and writers are buffered so they will all get thoroughly mixed up. Stick tone kind. Stick to one protocol. If you have object streams, use them for everything. And create them once for the life of the socket, not per message.

Related

BufferedReader readLine() have weird characeters

I have found a issue when I write and read data from sockets, in this time the socket are already open.
The code from server:
<pre>ServerSocket server = new ServerSocket(2001);
Socket socket = server.accept();
while(true){
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String readString = br.readLine();
System.out.println("result:\n"+readString)
}</pre>
The test I made from a client
<pre>Socket socket = new Socket("localhost", 2001);
Scanner consoleRead= new Scanner(System.in);
consoleRead.useDelimiter("\n");
ObjectOutputStream oo = new ObjectOutputStream(socket.getOutputStream());
while(true){
String s = consoleRead.next();
oo.writeUTF(s+System.lineSeparator());
oo.flush();
}</pre>
The first line is read perfectly... But the rest begin with weird characters.
Regards
If you are writing with ObjectOutputStream then read with ObjectInputStream insted of InputStreamReader
writeUTF()
Primitive data write of this String in modified UTF-8 format. Note that there is a significant difference between writing a String into the stream as primitive data or as an Object. A String instance written by writeObject is written into the stream as a String initially. Future writeObject() calls write references to the string into the stream.
Better is :- Write with OutputStreamWriter and read with InputStreamReader
For better understanding:- write the same thing in a file with ObjectOutputStream and then check what is getting written.

How to handle sending multiple messages over a socket connection?

I'm a bit of a beginner programmer so it's possible this is quite obvious and I'm overlooking the answer. But on to the question.
I have a two-part program (its a little more complicated than this example, but the situation is the same). The program has multiple messages fired between the client and the server. I have a PrintWriter on the server-side to send messages to the client, and on the client, I have a BufferedReader to read the messages sent.
When this example is run, I'm given two lines as output. The first message is both messages, and the second is NULL. What I am wondering is if there is a way to basically halt the server until I am ready for the second message, so that I can do something on the client-side before the second message is sent.
I am hoping to not use Thread.Sleep, as I would rather the Server wait around until the Client says it is ready.
This is the client:
public class Client{
public void run(){
Socket socket = null;
InputStream in = null;
BufferedReader reader = null;
try{
socket = new socket("LocalHost",1234);
in = socket.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
}
String messageFromServer = "";
try{
messageFromServer=reader.readLine();
}
System.out.println(messageFromServer);
String messageFromServer = "";
try{
messageFromServer=reader.readLine();
}
System.out.println(messagefromServer);
//close everything
}
}
This is the server:
public class Server{
public void run(){
ServerSocket server = null;
Socket client = null;
try{
server = new ServerSocket(1234);
client = server.accept();
}
PrintWriter writer = null;
OutputStream out = null;
try{
out = client.getOutputStream();
writer = new PrintWriter(out, true);
}
writer.write("Hi I'm a server");
//do some stuff that takes some time, user input, etc. etc.
writer.write("I'm still a server");
//close everything
}
Thanks :)
The problem with the way you currently have you code is the fact that you are using a BufferedReader, but the server is not terminating it's messages with a new line.
When you close the writer, the client is reaching the EOF or EOS and unblocking the read so it appears that both strings are being sent at once...
If you do something like...
writer.write("Hi I'm a server\n");
// This will force the message to be written to the client and picked up ;)
writer.flush();
writer.write("I'm still a server\n");
writer.flush();
Then you will get the messages seperatly...
You can use ObjectInputStream to read Objects instead of Strings.
This way you will read only one Message(String in your case) every call to ObjectInputStream.readObject();
BTW you can read the first message, "do something" and then read the second message. you don't have to read all of the sent messages at once.
If there are no other messages, then your thread will be blocked when trying to read an object from the ObjectInputStream.
Use it like:
ObjectInputStream inputStream = new ObjectInputStream( socket.getInputStream() )

Java readline() keeping socket open

I am trying to have my client connect to my server, and depending on the command send some string back to the client. Currently the app connects and can send strings to the server very nicely. However when I send the command which instructs the server to send something back it hangs. I found that the problem occurs when the client attempts to read the line send from the server.
Server
PrintWriter out = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
out.println("GETDATA" + "\n");
out.flush();
out.close();
Client
BufferedReader fromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
incomingLine = fromServer.readLine();
Log.d("HERE", "NOT " + incomingLine);
fromServer.close();
Thanks!
I made effectively this same mistake when I was first doing sockets as well.
Don't use PrintWriter with BufferedReader. They're incompatible. By comments, PrintWriter actually hides critical exceptions, so they shouldn't be used in networking. Instead, use a DataInputStream and DataOutputStream for communications.
client = new Socket(hostname, port);
inStr = new DataInputStream(client.getInputStream());
outStr = new DataOutputStream(client.getOutputStream());
Then, send and receive using writeUTF and readUTF, like so:
public void send(String data) throws IOException {
outStr.writeUTF(data); outStr.flush();
}
public String recv() throws IOException {return inStr.readUTF();}
The reason has to do with the UTF encoding; a BufferedReader expects a certain string encoding, which PrintWriter does not give. Thus, the read/write hangs.
The method readLine() expects an end of line character "\n" maybe that's your problem

Why does flush() effect println() on PrintWriter

I have the basic code for a server:
ServerSocket serverSocket = new ServerSocket(14000);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream());
String incoming;
while((incoming = in.readLine()) != null){
System.out.println("Client Says: " + incoming);
out.println("Client Says: " + incoming);
out.flush();
//if(incoming.equals("HELLO")) break;
}
clientSocket.close();
serverSocket.close();
I'm trying to further understand streams as they're giving me some serious headaches. From what I've read, println methods automatically flush for you, however this line is not delivered to the client unless the flush method is called afterwards? I'm just looking for a nice solid explanation of this?
To enable automatic flushing of the PrintWriter, the second argument of its constructor must be set to true.
I had this issue before, just:
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
That will make the difference. If you do not autoflush you can get some errors or receive data as null, it happened to me some time ago. Best regards.

Java socket reading issue when receives 0

I'm trying to communicate between 2 programs in Java with Java Sockets. I want to send some bytes through the socket as Data. Those bytes being data, their value can be anything (so could be 0 and possibly -1). I tried to use the DataInputStream class to handle the communications and works fine if i don't receive the byte 0 somewhere in the bytes i am trying to read, otherwise, it seems to block at this 0 byte and stop reading. Any one would have any ideas on the how or why this is happening and any ideas on how to work this around ? Thanks !
Please keep it simple,
Try using InputStream, InputStreamReader, BufferedReader, OutputStream, PrintWriter.
Client Side:
Socket s = new Socket();
s.connect(new InetSocketAddress("Server_IP",Port_no),TimeOut);
// Let Timeout be 5000
Server Side:
ServerSocket ss = new ServerSocket(Port_no);
Socket incoming = ss.accept();
For Reading from the Socket:
InputStream is = s.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
boolean isDone = false;
String s = new String();
while(!isDone && ((s=br.readLine())!=null)){
System.out.println(s); // Printing on Console
}
For Writing to the Socket
OutputStream os = s.getOuptStream();
PrintWriter pw = new PrintWriter(os)
pw.println("Hello");

Categories

Resources