Java: reconexão em uma tomada às vezes dá erro
-
21-08-2019 - |
Pergunta
Eu estou fazendo um protótipo cliente e servidor para que eu possa entender como lidar com reconecta.
O servidor deve criar um ServerSocket e ouvir sempre. Um cliente pode ligar, enviar seus dados e fechar seu soquete, mas não vai enviar uma mensagem tipo "eu sou feito e fechando" para o servidor. Por este motivo, o servidor recebe um EOFException
quando se faz um readByte()
uma vez que o cliente remoto fechou. No manipulador de erro para a EOFException
, que vai fechar o soquete e abrir uma nova.
Aqui está o problema: O cliente às vezes fica um SocketWriteError
quando ele faz a chamada outputStream.write()
mesmo depois de ele abre com sucesso o soquete / inputstream / outpustream. Pode ter algo a ver com a freqüência que eu estou abrindo e fechando esses soquetes. Uma coisa interessante é que o cliente faz um número arbitrário de escreve / fechar / reconecta antes crapping fora. Às vezes vai crap fora na primeira reconexão, outras vezes vai demorar 50 reconecta antes de ver o SocketWriteError
.
Aqui está o erro no lado do cliente:
java.net.SocketException: Connection reset by peer: socket write error at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) at java.net.SocketOutputStream.write(SocketOutputStream.java:115) at bytebuffertest.Client.main(Client.java:37)
Aqui estão alguns trechos de código:
SERVER:
public static void main(String[] args)
{
Server x = new Server();
x.initialize();
}
private void initialize()
{
ServerSocket s;
InputStream is;
DataInputStream dis;
while (true) //ADDED THIS!!!!!!!!!!!!!!!!!!!!!!
{
try
{
s = new ServerSocket(4448);
s.setSoTimeout(0);
s.setReuseAddress(true);
is = s.accept().getInputStream();
System.out.println("accepted client");
dis = new DataInputStream(is);
try
{
byte input = dis.readByte();
System.out.println("read: " + input);
} catch (Exception ex)
{
System.out.println("Exception");
dis.close();
is.close();
s.close();
}
} catch (IOException ex)
{
System.out.println("ioexception");
}
}
}
CLIENT:
public static void main(String[] args)
{
Socket s;
OutputStream os;
try
{
s = new Socket("localhost", 4448);
s.setKeepAlive(true);
s.setReuseAddress(true);
os = s.getOutputStream();
int counter = 0;
while (true)
{
try
{
os.write((byte) counter++);
os.flush();
os.close();
s.close();
s = new Socket("localhost", 4448);
s.setKeepAlive(true);
s.setReuseAddress(true);
os = s.getOutputStream();
} catch (Exception e)
{
e.printStackTrace();
System.err.println("ERROR: reconnecting...");
}
}
} catch (Exception ex)
{
ex.printStackTrace();
System.err.println("ERROR: could not connect");
}
}
Alguém sabe como se reconectar corretamente?
Solução
Não feche o ServerSocket em um erro, apenas .Aceitar () uma nova conexão.
O que eu faço normalmente é cada ServerSocket.accept time () retorna um socket, eu desovar fora de um thread para lidar com o envio e recebimento de que Socket. Dessa forma, você está pronto para começar a aceitar uma nova conexão, logo que alguém quer se conectar a você.