Error says the socket is closed... I can send to the server fine, I can recieve from the server fine, but as soon as I try to send and recieve I always get 'Socket is closed' error.
Server:
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream());
osw.write("return: "+decodedString);
osw.flush();
osw.close();
Client:
Socket c = new Socket("localhost",4040);
OutputStreamWriter osw = new OutputStreamWriter(c.getOutputStream());
osw.write("Test");
osw.flush();
osw.close();
BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
String decodedString;
while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
c.close();
This is because when you're closing one of the stream's (osw.close();) - the socked gets closed as well.
From Socket.getOutputStream's javadoc:
Closing the returned {#link java.io.OutputStream OutputStream} will close the associated socket.
Try flushing the streams but close them only when you're done.
Related
geniuses.
I want to used socket in Java.
Here is a part of my server side code:
ServerSocket ss = new ServerSocket(this.portNum);
while (!ss.isClosed()) {
Socket socket = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
System.out.println("reading");
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println("read");
System.out.println("writing");
bw.write(this.wsp.parse(new String(sb.toString())).toJSONString());
bw.newLine();
bw.flush();
System.out.println("wrote");
bw.close();
br.close();
socket.close();
}
ss.close();
And my client side (test) code is:
Socket socket = new Socket("143.248.135.60", 44450);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println("writing");
bw.write(str);
bw.newLine();
bw.flush();
System.out.println("wrote");
System.out.println("reading");
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
System.out.println("read");
br.close();
bw.close();
socket.close();
Both sides halt after printing "reading."
What's wrong with my codes?
Thank you for your help in advance!
Your application blocks at the servers site at this point:
while ((line = br.readLine()) != null) {
sb.append(line);
}
Your servers will read lines until the source stream gets closed (br.readLine() will return null when the end of stream has been reached). But this doesn't happen. It seems that your're expecting just a single line here so try this instead of the loop at the server side:
System.out.println("reading");
String line = br.readLine();
System.out.println("read");
Now about the name loop on the client side: The server will close the streams and the socket immediately after it has written its own data. So br.readLine() will return null on the client side after the first line was read. So it will do what you're expecting. But it will also works if you're replacing the code as I've suggested it for the server side.
Hope it helps.
Edit based on the clarification of the question (need to read multiple lines):
The easiest way based on your work is to use a control character like "End of transmission" (0x04 on ASCII).
Client code:
System.out.println("writing");
bw.write("Hello");
bw.newLine();
bw.write("World");
bw.newLine();
bw.write(0x04); // EOT control character
bw.newLine(); // This is needed for BufferedReader/Writer - even if we've used a EOT
bw.flush();
System.out.println("wrote");
Continued in the next commend...
Server code:
while ((line = br.readLine()) != null && !(line.length() > 0 && line.charAt(0) == 0x04)) {
sb.append(line).append(System.lineSeparator());
}
If you're not using ASCII or UTF8 please review your used encoding to choose the correct control character.
code to send data to server
BufferedReader keyRead = new BufferedReader(new InputStreamReader(System.in));
OutputStream ostream = sock.getOutputStream();
PrintWriter pwrite = new PrintWriter(ostream, true);
// receiving from server ( receiveRead object)
InputStream istream = sock.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
String receiveMessage, sendMessage;
while(true)
{
sendMessage = keyRead.readLine(); // keyboard reading
String enc = crypt.encrypt(sendMessage, serverPublicKey);
System.out.println("sending to server: "+enc);
pwrite.println(enc); // sending to server
pwrite.flush(); // flush the data
if((receiveMessage = receiveRead.readLine()) != null) //receive from server
{
//System.out.println(crypt.decrypt(receiveMessage, clientPrivateKey)); // displaying at DOS prompt
System.out.println(receiveMessage);
}
}
output after encryption looks like below on console
sending to server: YRJ7ZNgqSQ56nGc8ff7ktoybYEohQJS2R+Vh3YN1YfHipUS64MyFrrYAzL4CiTPv2WF7zvaJst1A
qsiPsv3/1Q==
code to receive on server
BufferedReader keyRead = new BufferedReader(new InputStreamReader(System.in));
// sending to client (pwrite object)
OutputStream ostream = sock.getOutputStream();
PrintWriter pwrite = new PrintWriter(ostream, true);
// receiving from server ( receiveRead object)
InputStream istream = sock.getInputStream();
BufferedReader receiveRead = new BufferedReader(new InputStreamReader(istream));
String receiveMessage, sendMessage;
while(true)
{
if((receiveMessage = receiveRead.readLine()) != null)
{
//System.out.println(crypt.decrypt(receiveMessage, serverPrivateKey));
System.out.println(receiveMessage);
}
sendMessage = keyRead.readLine();
String enc = crypt.encrypt(sendMessage, clientPublicKey);
System.out.println("sending to clinet: "+enc);
pwrite.println(enc);
pwrite.flush();
}
but data is received like
YRJ7ZNgqSQ56nGc8ff7ktoybYEohQJS2R+Vh3YN1YfHipUS64MyFrrYAzL4CiTPv2WF7zvaJst1A
rest of
qsiPsv3/1Q==
is received when i send something from server to client, please help me locate the problem, due to truncated data the decryption fails
You do not only encrypt the input but you also Base64 encode the encrypted bytes. Your Base64 encoder inserts line breaks every 76 characters, which is the standard for Base64 transfer encoding for MIME (RFC 2045). That is why on the server side your readLine() only reads in the first 76 characters.
You need to configure your Base64 encoder to not add line breaks.
I have a server and client application. They both use a BufferedWriter-InputStreamReader-InputStream to read information coming from the server, or coming from the client
I have it working so I can use
bw.write("command");
to execute a command on the server side, and output the information back to the client-side.
However, I am running into trouble doing it twice, for two different commands. Here's the code:
Server-sided code:
public void run() {
try {
while (true) {
socket.setTcpNoDelay(true);
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String input = br.readLine();
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
if (input.equals("increment")) {
bw.write(String.valueOf(totalBets.incrementAndGet()));
bw.newLine();
bw.flush();
} else if(input.equals("generate")) {
Random rand = new Random();
bw.write(String.valueOf(rand.nextDouble()*99));
bw.newLine();
bw.flush();
}
}
}
Client-sided code:
public void actionPerformed(ActionEvent arg0) {
try {
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
bw.write("increment" + "\n");
bw.flush();
String id = br.readLine();
bw.write("generate");
bw.flush();
String roll = br.readLine();
}
}
The first String id gets the output from running the bw.write("increment"), but when I try to run bw.write("generate"), it freezes when running the line: String roll = br.readLine();
Any help?
Thank you!
I suggest that you use PrintWriter rather than BufferedWriter. Use BufferedReader to read without leaving data in the underlying operating system's buffers, so they will be buffered at application level, but for writing you want it to go out as soon as you send one complete 'command'.
With a PrintWriter you can also use println which should solve your problem.
You're losing data, or risking it, by creating multiple BufferedReaders. Use the same one for the life of the socket. Ditto the BufferedWriter.
I have a Server-Client program where I send a small messsage to the client using JLabel. When that message is recieved from server that particular client must send a response immediately. But it is not sending any message . Can somebody look at my code and tell me where my mistake is?
//SERVER
void connect_clients()
{
try {
ServerSocket listener = new ServerSocket(7700);
jButton1.setText("Server Running!");
jButton1.setEnabled(false);
while (true) {
socket = listener.accept();
socketList.add(socket);
//socketList.add(listener.accept());
BufferedReader ed = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String tmp = ed.readLine();
System.out.print("I Recieved :"+tmp);
}
}
catch(IOException ex)
{
JOptionPane.showMessageDialog(null,ex);
}
}
//CLIENT
void connect_server() throws IOException
{
try {
// TODO code application logic here
String serverAddress = JOptionPane.showInputDialog(
"Enter IP Address of a machine that is\n" +
"running the date service on port 9090:");
s = new Socket(serverAddress, 7700);
while(true){
BufferedReader input =
new BufferedReader(new InputStreamReader(s.getInputStream()));
String answer = input.readLine();
System.out.println(answer);
if(answer != null)
{
PrintStream pr = new PrintStream(s.getOutputStream());
InputStreamReader rd = new InputStreamReader(System.in);
BufferedReader ed = new BufferedReader(rd);
String temp = ed.readLine();
pr.println(temp);
JOptionPane.showMessageDialog(null,"Answer is not null"); //THIS WORKS
}
}
}
catch (ConnectException e) {
JOptionPane.showMessageDialog(null, e);
}
catch (SocketException e) {
JOptionPane.showMessageDialog(null, e);
}
}
Some points that you missed in your implementation:
the streams and sockets are never closed
in the client i do not see the point of the endless loop
the client should initialize the communication by sending a message via output stream (not to try to read first)
For a simple example the steps should be:
Start sever to listen and once a connection is established to read the message (you did)
The client should sent a message via output stream and close the steams and the socket
The severs should close the streams and the sockect for the established connection
Example:
//Server
socket = listener.accept();
BufferedReader ed = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter pr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream());
String tmp = ed.readLine();
System.out.print("I Recieved :"+tmp);
String msg = "Message received";
pr.write(msg,0,msg.length());
pr.newLine();
ed.close();
pr.close();
socket.close();
//Client
BufferedWriter pr = new BufferedWriter(new OutputStreamWriter(s.getOutputStream());
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String sendMessage = "Send Message";
pr.write(msg,0,msg.length());
pr.newLine();
String answer = input.readLine();
System.out.println(answer);
JOptionPane.showMessageDialog(null,"Answer is not null");
input.close();
pr.close();
s.close();
UPDATE
reading from input stream continuously:
BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while((line=input.readLine())!=null){
//do something with line
}
I will suggest a simple approach where server is sending the hi msg to client.
For server:
//Server
ServerSocket ss=new ServerSocket(3554);
socket = ss.accept();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getOutputStream()));
String msg ="Hi from server"
bw.write(msg);
String msgFromClient=br.readLine();
System.out.println(msgFromClient);
bw.close();
socket.close();
For Client:
//Client
Socket socket=new Socket("localhost",3554)
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String received = input.readLine();
System.out.println(received);
bw.write("Client recieve :"+received);
br.close();
bw.close();
socket.close();
What is happenning:
Main server -> String("isalive") => Other server
Other server -> String("alive") => Main server
Ports and stuff are configured (both servers are dedicated machines)
And code. The place where stuff seem to break is (i added debug messages....)
reader.readLine();
Main server code:
Socket clientSocket = new Socket(key, 6789);
if(clientSocket.isConnected() && !clientSocket.isClosed()){
String in;
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(isalive);
outToServer.flush();
//it wont go pass this one
in = inFromServer.readLine();
if(in.equals("alive")){
if(!Data.hosts.get(key)){
Data.hosts.put(key, true);
}
}
outToServer.close();
inFromServer.close();
clientSocket.close();
It wont go pass this one because it will stop at the other server.
Code:
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
//stuck here
rec = inFromClient.readLine();
if(rec.equals("isalive")){
outToClient.writeBytes("alive");
}
inFromClient.close();
outToClient.flush();
outToClient.close();
connectionSocket.close();
Thanks in advance.
You should not combine DataOutputStream and BufferedReader.
Consider using PrintWriter instead and specify character encodings as well (to be safe).
PrintWriter writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
writer.println("Hello.");
writer.flush();
reader.readLine();