Reputation: 10651
I have a socket client that hangs whenever I try to read the input stream from the socket.
DataInputStream dis = new DataInputStream(socket.getInputStream());
int singleByte;
while((singleByte = dis.read()) != -1) { //<-- hangs here
char c = (char)singleByte;
// append character
message_string += c;
}
while((singleByte = dis.read()) != -1) {
I have confirmed that the server is echoing back what I send it in raw ASCII.
What am I not understanding? Why is it hanging when trying to read the server response?
Server side (handles the request):
class HandleInputBuffer implements Runnable {
private String msg = "";
private String response = "8";
public HandleInputBuffer(String str) {
this.msg = str;
}
@Override
public void run() {
String exception_msg = "";
// process incoming message
try {
if(msg!=null){
if(msg.length()>0){
// create and send reply
String response = "8";
// ****************************
// create and send response
// ****************************
try {
response = msg;
output_stream = new DataOutputStream(client_socket.getOutputStream());
output_stream.writeInt(response.getBytes("US-ASCII").length);
output_stream.write(response.getBytes("US-ASCII"));
output_stream.flush();
output_stream.close();
//client_socket.shutdownOutput();
client_socket.close();
} catch (IOException e) {
e.printStackTrace();
try{output_stream.flush();} catch (IOException e1) {}
try {client_socket.close();} catch (IOException e1) {}
try {updateConversationHandler = new Handler();} catch (Exception e1) {}
return;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client side refactor - This code hangs int length = dis.readInt();
InetAddress serverAddr = InetAddress.getByName(edit_ip_address.getText().toString());
if(socket == null){
socket = new Socket(serverAddr, Integer.parseInt(edit_port.getText().toString()));
}
// send bytes
output_stream = new DataOutputStream(socket.getOutputStream());
output_stream.write(command.getBytes("US-ASCII"));
DataInputStream dis = new DataInputStream(socket.getInputStream());
int length = dis.readInt();
byte[] buffer = new byte[length]; //<-- OutOfMemoryException
dis.readFully(buffer);
for (byte b:buffer){
char c = (char)b;
message_string += c;
}
Upvotes: 1
Views: 3667
Reputation: 311054
This loop will block until the peer closes the connection.
Ergo the peer is not closing the connection.
EDIT The correct way to read what you're sending is as follows:
You need to read the integer length word that you're writing. It doesn't magically appear via available():
int length = dis.readInt();
byte[] buffer = new byte[length];
dis.readFully(buffer);
But I would throw the sending and receiving code away and use readUTF()/writeUTF()
, assuming the data is character data. If it isn't, you shouldn't be assembling it as a String.
EDIT 2 Proof that this works:
Client.java:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client
{
public static void main(String[] args) throws IOException
{
try (Socket s = new Socket("localhost", 9999))
{
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeInt(1);
out.writeBytes("8");
DataInputStream in = new DataInputStream(s.getInputStream());
int count = in.readInt();
System.out.println("Reading "+count+" bytes");
byte[] buffer = new byte[count];
in.readFully(buffer);
System.out.write(buffer, 0, count);
System.out.println();
}
}
}
Server.java:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server
{
public static void main(String[] args) throws IOException
{
try (ServerSocket ss = new ServerSocket(9999))
{
try (Socket s = ss.accept())
{
DataInputStream in = new DataInputStream(s.getInputStream());
int count = in.readInt();
System.out.println("Reading "+count+" bytes");
byte[] buffer = new byte[count];
in.readFully(buffer);
System.out.write(buffer, 0, count);
System.out.println();
DataOutputStream out = new DataOutputStream(s.getOutputStream());
out.writeInt(count);
out.write(buffer, 0, count);
}
}
}
}
If yours doesn't, you are reading something else from the socket, or writing something else to it, or not running the code you think you're running.
Upvotes: 2