I got server-client application. On the client side, I am using this I/O stream to output data:
out = new PrintWriter(socket.getOutputStream(), true);
out.println("yeah");
On the server side I am trying to read the product by this line:
DataInputStream din = new DataInputStream(s.getInputStream());
String clientId = din.readUTF();
The server reaches the above statement and stops there. What's the problem? Are the two I/O streams not compatible with each other?
There are no exceptions thrown by either party, no output. I simply added System.out.println() before and after the above statement I=and I determined that the program does not cross this line:String clientId = din.readUTF();
You should use the DataOutputStream.writeUTF() method if you want to read from the other end of the socket with DataInputStream.readUTF(). See the Javadoc on DataInput for more detail on why. As an alternative, try using a buffered reader or scanner to read in your data.
Related
Hello stack overflow world, I've been struggling with the most straight forward and common problem within Java IO, for some time, and now need your help to tackle it.
Check out this piece of code I have in a try block, within a thread.run():
// connect to client socket, and setup own server socket
clientSocket = new Socket(serverHostname, CLIENT_PORT);
//send a test command to download a file
String downloadFileName = "sample.txt";
DataOutputStream dataOutputStream = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Sending a request to download file : " + downloadFileName + " from user: Arsa node"); //todo: replace with node user later
dataOutputStream.writeUTF("D/sample.txt");
//close socket if host isn't detected anymore, and if socket doesn't become null suddenly
dataOutputStream.flush();
dataOutputStream.close();
System.out.println("****File has been sent****");
in = new DataInputStream(clientSocket.getInputStream());
byte[] retrievedFileData = new byte[8036];
if (in.readInt() > 0) {
System.out.println("Starting file download!");
in.read(retrievedFileData);
System.out.println("File data has been read, converting to file now");
//closing input stream will close socket also
in.close();
}
clientSocket.close();
2 Main questions that have been confusing me to death:
Why does dataOutputStream.close() need to be run for writeUTF to actually send my string to the server socket, I find that when I don't have dos.close(), data isn't retrieved on the other side, further because I close it, I no longer can read from the socket - as it seems the socket connection becomes closed when the Output Stream is previously closed...
What's a better way, following some sort of pattern to do this? For context, all I'm trying to do is write the filename I'm looking to download to my client, then read the response right away, which I expect to be bytes with the file, any error handling I will consider as a part of my development.
Overall, it shouldn't be complicated to write something to a socket, then read and ingest it's response...which doesn't seem to be the case here,
any help would be greatly appreciated! If the ServerSocket code snippet is needed I'm happy to share.
The observed behavior is just a side-effect of close(), as it calls flush() before closing to make sure any buffered data is sent. To solve your problem, you need to call the flush() method instead of closing.
This behavior is not unique to DataOutputStream: a lot of other OutputStream (or Writer) implementations apply buffering, and you will need to flush when you want to ensure the data is sent to the client, written to disk or otherwise processed.
BTW: The DataOutputStream and DataInputStream is for a very specific type of data serialization protocol that is particular to Java. You may want to consider carefully if this is the right protocol to use.
I'm using java and sockets to comunicate a client/server application.
I want to send a message to server like this:
is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
pw = new PrintWriter(socket.getOutputStream());
pw.println("MESSAGE");
pw.flush();
And that worked well, but then after that I'm trying to send another message
pw.println("SECOND MESSAGE");
pw.flush();
And the second message is not sending! What can I do?
Ensure that your server side is consistently reading for more input. If you only have it say for example performing:
bufferedReader.readLine();
only once then this is the reason you think it isn't receiving it. It probably is if the connection isn't closed.
Another possibility since you said it isn't "sending" the second message, is ensure the socket connection remains open and that the reader is still open on the server side and that it wasn't closed after the first message was received.
use flush() when all the messages are sent.
I am trying to learn socket programming. I wrote client using InputStreamReader and with BufferedReader I read the msg sent from server.
For server if I write PrintWriter with print method it works and with write method it's not, why?
And OutputStreamReader is not at all useful as it does not have print method and with write, I am not getting messages in client side.
Client:
Socket c=new Socket("143.22.165.27",6000);
InputStreamReader isr=new InputStreamReader(c.getInputStream());
BufferedReader br=new BufferedReader(isr);
String s=br.readLine();
System.out.println(s);
Server
Socket sock=s.accept();
OutputStreamWriter out =
new OutputStreamWriter(sock.getOutputStream());
out.write("...........");
I assume you are using the readLine() method on the client's BufferedReader. So my guess would be that you aren't writing any newline characters when you use the write() methods on the server. Thus, the client never reaches the end of a line. A PrintStream or a PrintWriter adds the newline characters for you whenever you call a println() method.
Of course, without any code or even a description of the problem, it's hard to say for sure.
You must use out.flush() every time when you want to sent portion of data via out.write(msg).
I'm writing a Java client/server application. It should allow clients to send text data to the server. This kind of communication should be repeatable many times using the same connection.
I write it like this:
// On a server:
ServerSocket serverSocket = new ServerSocket(port);
Socket socket = serverSocket.accept();
socket.setKeepAlive(true);
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if (reader.ready()) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
// do something with line
}
}
// On a client:
Socket socket = new Socket(host, port);
socket.setKeepAlive(true);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("Some data from client to server");
writer.flush();
The problem is: I can't read on a server before I close OutputStream on a client. Or I can't open OutputStream on a client again, if it was already closed. How can I do continuous sending and reading of data?
You need two threads at both ends, one for reading data and other one for writing data.
The problem is: I can't read on a server before I close OutputStream on a client.
Yes you can. You just can't get to the case where readLine() returns null. It isn't the same thing.
Or I can't open OutputStream on a client again, if it was already closed.
Of course not. You have to create a new Socket.
How can I do continuous sending and receiving of data?
I don't understand the question. The code you posted doesn't attempt that.
If your goal is to send many mesages over the same socket connection, these messages will have to be delimited by an application-level protocol. In other words, you won't be able to rely on any system calls like reader.ready() or reader.readLine() == null to detect the end of the message on te server.
One way to achieve this is to begin each message with its length in characters. The server will then read exactly that number of charecters, and then stop and wait for a new message. Another is to define a special character sequence which concludes each message. The server will react to reading that particular sequence by ending the reading of the current message and returning to the "wait for new message" state. You must ensure that this sequence never appears in the message itself.
Suppose I have following Java code on a server:
Socket aSocket = new Socket(aInetaddr, aPort); //aSocket is a client i m connecting to
InputStream input = aSocket.getInputStream();
Socket bSocket = new Socket(bInetaddr, bPort); //bSocket is a client i m connectin to
Now what I would like to achieve is, to pass the InputStream "input" from the aSocket to the bSocket. I have no information about whats coming from the InputStream, or how it is used in the end.
The whole transfer of data has to pass my server, I can't make a direct connection between the 2 clients.
Get the output stream for the second socket and then you can do this trivially using Apache Commons IOUtils.copy(). Amongst many variants there's one that takes an input and output stream as arguments.