Clarifications while reading/writing Java socket streams - java

I have few questions in java socket programming.
while reading the inputstream in client socket, if it throws IO exception; then do we need to reconnect the server socket/ reintialize the client socket again?
if we close the output stream, will it closes the client socket?
in client socket, if the message read from the inputstream is different as what we expected; do we have any standard to handle this?

while reading the inputstream in client socket, if it throws IO exception; then do we need to reconnect the server socket/ reintialize the client socket again?
Yes, unless it was a SocketTimeoutException on a read operation.
if we close the output stream, will it closes the client socket?
Yes.
in client socket, if the message read from the inputstream is different as what we expected; do we have any standard to handle this?
No. If the message is completely unrecognizable, you wil probably want to sever the connection. If it's a recognized message but out of sequence, it may be either a programming error or a condition you didn't think of during design. Solution: think about it now.

Related

How to close a Java's socket's outputstream while keeping the inputstream open to get a result?

I'm sending a message to a server, which passes correctly.
But, when trying to read the result, I get an exception that the Socket is closed.
Any idea how to close the socket's outputstream while keeping the socket and socket's inputstream open to get the result?
Client code:
Socket socket = new Socket("localhost", 9090);
String message = "Some message";
new OutputStreamWriter(socket.getOutputStream(), Charsets.UTF_8)
.append(message)
.close();
// The following line throws the exception when socket.getInputStream() is called:
String fromServer = CharStreams.toString(new InputStreamReader(socket.getInputStream(), Charsets.UTF_8));
Exception:
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:903)
at alik.server.test.Client.pingServer(Client.java:24)
From the javadoc of Socket.getOutputStream():
Closing the returned OutputStream will close the associated socket.
In other words, don't close the output stream until you are done with the input stream. Closing the input stream will also close the socket (and as a result, also the output stream).
You could use Socket.shutdownOutput() to prevent further writing to the socket, but I don't really see the point of using that, and it could result in the peer closing its socket prematurely, as Stephen C explains in the comments:
The peer should only see the closed stream if it reads. What happens
next will depend on how it responds to seeing the closed stream.
You can't close an OutputStream without closing the socket(See two links below). Is there a specific reason why you need to do this?
You would need to finish read/writing before you close the socket and it's input/output streams.
Returns an output stream for this socket.
If this socket has an associated channel then the resulting output stream delegates all of its operations to the channel. If the channel is in non-blocking mode then the output stream's write operations will throw an IllegalBlockingModeException.
Closing the returned OutputStream will close the associated socket.
Behavior of Java sockets when closing output stream
https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#getOutputStream()
As mentioned by Joseph, I don't think you should close the OutputStream before opening the InputStream.
According to Oracle Docs (https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html), the correct order is:
Open a socket.
Open an input stream and output stream to the socket.
Read from and write to the stream according to the server's protocol.
Close the streams.
Close the socket.
To only close the output stream, use
socket.shutdownOutput()
See docs
You can't. Closing a socket input or output stream closes the other stream and the socket.
However the real problem here is that the peer is trying to read until end of stream before it sends anything back. This is an applicaton protocol issue. You could overcome it by shutting down the sending socket for output after sending everything that is to be sent, as mentioned by #MarkRotteveel, but this restricts you to one request/response per connection.
It would be better to review your application protocol to discover how the peer can know where the end of a request is, and only read that far before replying. For example, possibly you should be sending lines.

Closing a Java Socket safely without server side exceptions

What is the Safest way to close a socket connection from client side. Shutdown inputs first or close() the connection straight away?
If your protocol (top of TCP) does not contain any message/handshake for closing a session, then you must do it by closing TCP connection.
There are two ways to close a TCP connection:
graceful: uses TCP SYN, all undelivered data is transferred (tried). read() of InputStream returns -1;
ungraceful: uses TCP RST, all undelivered data is discarded. read() of InputStream throws an exception.
Both can be done in java with close() function of Socket.
Graceful is the default. Ungraceful, if setsolinger(true,0); is done before the close().
Closing the socket already shuts down both input and output. You don't need to do either of those explicitly.

Can ServerSocket write to client before reading from client?

After a ServerSocket accepts a connection to a client, can the ServerSocket start writing data to the client before the client sends a message? When I try to write to the client from the ServerSocket first, the client is blocking forever tyring to read it. However, if have the client send a message to the server first, the I/O streams between them work OK.
The ServerSocket can neither read nor write, but the accepted Socket can do both, in either order, or simultaneously.
Probably you are reading lines but not sending lines, or else not flushing a buffered output stream or writer.
Yes, you are correct that I meant getting the Socket from the accept() method.
My problem was very simple. The client was doing a readLine() method call but the server was not sending the "\n" character.

How to redirect input and output of a Process over a TCP socket connection? (java)

I'd like to know how I can redirect the input and output of a system process over a TCP connection from the server-side. This would result in the client being able to interact with said process.
So far I know how to actually establish a simple TCP connection, and I can get the input and output streams of the connection socket using the getInputStream() and getOutputStream() methods.
I can also get the output and input streams of a Process (after initializing the process via ProcessBuilder.start() method) using its getInputStream() and getOutputStream() methods.
So I end up with two sets of input and output streams. What I want to know is how to connect (may be using the wrong word here) the output and input streams of the Process with the output stream of the connection socket, so that the client on the other side of the TCP connection can interact with the Process.
If it matters, I'm using BufferedInputStreams and BufferedOutputStreams.
Any information regarding this problem is greatly appreciated, thanks!
To redirect the output streams of a process to socket, try the following code
System.setOut( new PrintStream(mySocket.getOutputStream(),true))
Visit
http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#setOut%28java.io.PrintStream%29
Similarly, explore the System.setErr() and System.setIn() for error and input streams respectively!

Chat server writing to closed sockets

Essentially I have a server class and a client class, the client creates a socket and sends whatever you type into the server, which gets written to the output streams of a vector of sockets from all the existing clients. It works well except when you close a chat client, after which the next message sent gives the following exception:
java.net.SocketException: Software caused connection abort: socket write error
I think what's happening is that the socket closed by the client is either not closing the socket in the server's vector of sockets, or that even when it's closed, it remains in the vector and then tries to write to a closed socket. Does this sound like what might be happening? I don't understand exactly what the socket.close() method does regarding the socket it's connected to.
You close the socket on the client side, but on the server side it is not closed and this is why you get this exception.
In a graceful close you should send a CLOSE message from your client which will close the socket on the server side.
If a socket on the client was closed then you must handle your exception on the server side e.g. by removing it from your vector of sockets.
If the client closes his socket you will read EOS at the server (read() returns -1, readLine() returns null,readXXX() throws EOFException for any other X), or get an IOException: connection reset by peer when writing, probably not on the first write. If either of these things happens you must close the socket in the server and forget about that client in all ways.
I don't think it's like both sides of connection are holding together by hands, and if you split them they always will feel it. Check if socket is closed before sending and catch exceptions to solve this problem.

Categories