quinta-feira, 12 de fevereiro de 2015

Java: comunicação bidirecional com sockets - aprimorado

Olá pessoal,
Alguns dias atrás eu postei um exemplo de código para comunicação bi-direcional entre cliente e servidor via socket. Hoje eu trago para vocês uma versão aprimorada do programa, que tem as seguintes funcionalidades:

  1. O cliente pede que o usuário digite a mensagem que será enviada. Ao final da mensagem é enviada um caracter 0x04 de End Of Transmission EOT.
  2. O servidor recebe a mensagem e informa que a mensagem está ok
  3. O cliente está configurado com um timeout de 10 segundos. Caso a mensagem de retorno não seja recebida, o cliente aborta e retorna o prompt
  4. Caso o cliente desconecte, o servidor fecha a conexão


Os códigos estão logo abaixo:

SimpleServer.java

package servidor;
import java.io.*;
import java.net.*;
public class SimpleServer {
private int port;
private ServerSocket serverSocket;
public static OutputStream out;
public static InputStream in;
public static Socket client;
public int data;
public SimpleServer() {
port = 1775;
try {
serverSocket = new ServerSocket(port);
} catch (Exception e) {
e.printStackTrace();
}
}
public void start() {
try {
  client = serverSocket.accept();
  out = client.getOutputStream();
  in = client.getInputStream(); } catch (Exception e) {
 e.printStackTrace();
}
}
public static void fecharConexao() throws IOException {
 out.close();
 in.close();
 client.close();
}
public void receberMsg() throws IOException {
  int recebido=0;
  long tempoEspera = System.currentTimeMillis() + 10000;
  while (System.currentTimeMillis() < tempoEspera) {
  while ((data = (int)in.read()) != 4) {
   System.out.print((char)data);
   recebido=data;
  }
  System.out.println( "\n");
  enviarMsg();
  return;
  }
  return;
}
public void enviarMsg() throws IOException {
String message = "Mensagem recebida pelo servidor. Tudo ok!";
   out.write(message.getBytes());
   out.write(4);
 out.flush();
 return;
}
public static void main(String[] args) throws IOException { System.out.println("Servidor iniciado.\n");
SimpleServer server = new SimpleServer();
server.start();
System.out.println("Aguardando mensagens\n");
while(true){
try{
server.receberMsg();
} catch(Exception e){
System.out.println("Cliente desconectou");
fecharConexao();
break;
}
}
}
}

SimpleClient.java

package cliente;
import java.net.*;
import java.io.*;

public class SimpleClient {
private InetAddress address;
private int port;
public static OutputStream out;
public static InputStream in;
public static Socket socket;
public int data;
public SimpleClient() {
try {
address = InetAddress.getLocalHost();
port = 1775;
} catch (Exception e) {
e.printStackTrace();
}
}
public void connect() {
try {
 socket = new Socket(address, port);
 out = socket.getOutputStream();
 in = socket.getInputStream();
 socket.setSoTimeout(10*1000);

} catch (Exception e) {
 e.printStackTrace();
 System.out.println("Não foi possível conectar ao servidor");
}
}

public void enviarMsg() throws IOException {
 String message = null;
 System.out.println("Por favor, digite a mensagem:\n");
 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
 message = in.readLine();
 out.write(message.getBytes());
 out.write(4);
 out.flush();

 System.out.println("\n");

  receberMsg();
}
public void receberMsg() throws IOException {
  int recebido=0;  
  while ((data = (int)in.read()) != 4) {
   System.out.print((char)data);
   recebido=data;
  };
  System.out.println("\n");
    return;
}
public void fecharConexao() throws IOException {
 out.close();
 in.close();
 socket.close();
}

public static void main(String[] args) throws IOException {
System.out.println("Iniciando programa cliente:\n");
SimpleClient client = new SimpleClient();
client.connect();
while (true){
try { client.enviarMsg();
} catch(Exception e) {
System.out.println("Timeout para receber confirmação do servidor.");
}
}
}
}