Caros,
estou tentando implementar um chat, seguindo o exemplo apresentado no livro.
Bem, consegui me conectar ao ServerMessenger certinho...
Quando eu envio a primeira mensagem... dá tudo certo...
A mensagem chega no servidor e é distribuída para todos os clientes....
Só que quando envio a segunda mensagem ou o outro cliente vai responder, acontece o seguinte:
No server dá o seguinte erro:
[color=red]
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.BufferededReader.fill(Unknown Source)
at java.io BufferededReader.readLine(Unknown Source)
at java.io BufferededReader.readLine(Unknown Source)
at chat.ReceivingThread.run(ReceivingThread.java:51)
[/color]
A minha classe ReceivingThread é essa:
[code]package chat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.net.Socket;
import java.util.StringTokenizer;
// Thread que espera mensagens de um cliente
// particular e envia mensagens para um MessageListener;
// espera novas mensagens de clientes do MessengerServer em Threads separadas
public class ReceivingThread extends Thread implements SocketMessengerConstants{
private BufferedReader input;
private MessageListener messageListener;
private boolean keepListening = true;
// construtor
public ReceivingThread(MessageListener listener, Socket socketCliente) {
// invoca o construtor da super classe para dar nome à Thread
super("ReceivingThread: " + socketCliente);
// configura o ouvinte para o qual a novas mensagens devem ser enviadas
messageListener = listener;
// configura o tempo máximo de espera para leitura do socketCliente
// e cria um BufferedReader para ler as mensagens que chegam
try {
socketCliente.setSoTimeout(30000);
input = new BufferedReader(new InputStreamReader(socketCliente.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
// espera novas mensagens e as envia ao MessageListener
public void run(){
String message;
// espera novas mensagens até que seja parado
while (keepListening){
// lê mensagem do BufferedReader
try{
message = input.readLine();
// trata exceção quando o tempo máximo para leitura é esgotado
}catch (InterruptedIOException interruptedIOException){
continue;
}catch (IOException e){
e.printStackTrace();
break;
}
// assegura que a mensagem não está vazia
if(message != null){
// separa a mensagem em tokens para recuperar
//o nome do usuário e o corpo da mensagem
StringTokenizer stringTokenizer = new StringTokenizer(message, MESSAGE_SEPARATOR);
// ignora mensagens que não têm um nome de usuário e um corpo de mensagem
if(stringTokenizer.countTokens() == 2){
// envia mensagem para o MessageListener
messageListener.messageReceived(
stringTokenizer.nextToken(), // nome do usuario
stringTokenizer.nextToken()); // corpo da mensagem
}
else
// se recebeu mensagem de desconexão, para de esperar mensagens
if(message.equalsIgnoreCase(MESSAGE_SEPARATOR + DISCONNECT_STRING)){
stopListening();
}
}
}
// fecha o BufferedReader (também fecha o socket)
try{
input.close();
}catch (IOException e){
e.printStackTrace();
}
}
// para de esperar por mensagens
public void stopListening(){
keepListening = false;
}
}[/code]
E no cliente dá o seguinte erro:
[color=red]java.net.SocketException: Socket closed
at java.net.PlainDatagramSocketImpl.receive0(Native Method)
at java.net.PlainDatagramSocketImpl.receive(Unknown Source)
at java.net.DatagramSocket.receive(Unknown Source)
at chat.PacketReceivingThread.run(PacketReceivingThread.java:62)[/color]
A minha classe PacketReceivingThread é a seguinte:
[code]package chat;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.StringTokenizer;
public class PacketReceivingThread extends Thread implements SocketMessengerConstants{
// MessageListener ao qual as mensagens devem ser entregues
private MessageListener messageListener;
// Multicatsocket para receber as mensagens transmitidas
private MulticastSocket multicastSocket;
// InetAddress do grupo de mensagens
private InetAddress multicastGrupo;
// indicador para terminar a PacketReceivingThread
private boolean keepListening = true;
// construtor
public PacketReceivingThread(MessageListener listener) {
super("PacketReceivingThread");
messageListener = listener;
// conecta o MulticastSocket ao endereco e a porta de multicast
try{
multicastSocket = new MulticastSocket(MULTICAST_LISTENING_PORT);
multicastGrupo = InetAddress.getByName(MULTICAST_ADDRESS);
// junta-se ao grupo de multicast para receber mensagens
multicastSocket.joinGroup(multicastGrupo);
// ajusta tempo máximo de 5 segundos para esperar novos pacotes
multicastSocket.setSoTimeout(20000);
}catch (IOException e) {
e.printStackTrace();
}
}
// espera as mensagens do grupo de multicast
public void run(){
// espera as mensagens até ser parada
while(keepListening){
// cria buffer para mensagens que chegam
byte[] buffer = new byte[MESSAGE_SIZE];
// cria DatagramPacket para mensagen que chega
DatagramPacket datagramPacket = new DatagramPacket(buffer, MESSAGE_SIZE);
// recebe novo DatagramPacket (chamada bloqueante)
try{
multicastSocket.receive(datagramPacket);
}catch (InterruptedIOException interruptedIOException){
interruptedIOException.printStackTrace();
}catch (IOException e){
e.printStackTrace();
break;
}
// coloca dados da mensagem em uma String
String message = new String(datagramPacket.getData());
// assegura que a mensagem não está vazia
if(message != null){
// elimina espaço em branco extra no fim da mensagem
message = message.trim();
// separa a mensagem em tokens para separar nome do usuario do corpo da mensagem
StringTokenizer stringTokenizer = new StringTokenizer(message, MESSAGE_SEPARATOR);
// ignora mensagens que não têm nome de usuario e corpo
if(stringTokenizer.countTokens() == 2){
// envia a mensagem para o MessageListener
messageListener.messageReceived(stringTokenizer.nextToken(), stringTokenizer.nextToken());
}
}
// sai do grupo de multicast e fecha o MulticastSocket
try{
multicastSocket.leaveGroup(multicastGrupo);
multicastSocket.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
// para de esperar por novas mensagens
public void stopListening(){
keepListening = false;
}
}[/code]
Depurando eu percebi que na classe ReceivingThread do Servidor...
A execução fica muito tempo na linha 51
[code]message = input.readLine();[/code]
Até cair na Exception InterruptedIOException
Alguém sabe me dizer o porquê?
Obrigada!