I've got a Client and a Server. The client simply sends 1 line of input to the server and then prints the response.
I'm getting a
SocketException (Software caused connection abort: recv failed)
[...]
at java.io.InputStreamReader.read(InputStreamReader.java:168)
at hw3.Client.readLine(Client.java:37)
at hw3.Client.main(Client.java:28)
The debugger tells me that the socket is not closed at the time of the read, what else can cause this exception?
I think I'm running into issues because of the threading, does anything stick out as "doing it wrong"?
public class Client
{
public static final int PORT = ReversingEchoServerDispatcher.PORT;
private static final String host = "localhost";
private static Socket sock;
public static void main(String[] args)
throws IOException
{
try(Socket sock = new Socket(host, PORT);
InputStreamReader clin = new InputStreamReader(sock.getInputStream());
OutputStream clout = sock.getOutputStream();
Scanner sc = new Scanner(System.in))
{
Client.sock = sock;
byte[] cl = sc.nextLine().getBytes("UTF-8");
clout.write(cl);
System.out.println(readLine(clin));
}
}
private static String readLine(InputStreamReader in)
throws IOException
{
StringBuilder sb = new StringBuilder();
for(int i = in.read(); i != -1; i = in.read())
{
char c = (char) i;
if(c != '\n') sb.append(c);
else break;
}
return sb.toString();
}
}
public class ServerDispatcher
{
public static final int PORT = 8034;
public static void main(String[] args)
{
try (ServerSocket serversock = new ServerSocket(PORT))
{
while(true)
{
Socket socket = serversock.accept();
ServerLogic sv = new ServerLogic(socket);
new Thread(() -> {
try {
sv.run();
} catch (IOException ex) {
ex.printStackTrace(System.err);
}
}).start();
}
}
catch(IOException e)
{
e.printStackTrace(System.err);
}
}
}
For the record, the ServerLogic class looks something like the following. My exit code is 1, not -999, so it's not that socket.close() is failing
class ServerLogic
{
Socket socket;
public
ServerLogic(Socket s)
{
this.socket = s;
}
public void run()
throws IOException
{
try(InputStreamReader in = new InputStreamReader(socket.getInputStream());
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream()))
{
StringBuilder sb = new StringBuilder();
while(in.ready()) {
char c = (char) in.read();
if(c == '\n') {
String str = process(sb);
if(str != null) out.write(str);
else return;
} else {
sb.append(in.read());
}
}
} finally {
try {
socket.close();
} catch(IOException ex) {
ex.printStackTrace(System.err);
System.exit(-999);
}
}
}
private static String process(StringBuilder sb)
{ /* ... */ }
flush()
on clout on the client side after the write. – MeBigFatGuy