Sockets e Threads em Java UNIVERSIDADE TECNOLÓGICA FEDERAL DO PARANÁ DEPARTAMENTO ACADÊMICO DE ELETRÔNICA PROF. VITOR YANO Comunicação em rede em Java A comunicação em rede na linguagem Java é implementada pelo pacote java.net; As classes dessa biblioteca, por sua vez, implementam sockets, que podem ser unicast (para um único destinatário) ou multicast (para um grupo de destinatários). Existem dois modos de utilização de sockets IP: Orientado a conexão (protocolo TCP) Orientado a datagrama (protocolo UDP) Comunicação em rede em Java Modo orientado a conexão (TCP/IP): Serviços mais confiáveis; Garantia de ordem dos pacotes de dados; Possibilidade de utilização de fluxos de dados; Comportamento do servidor diferente do cliente; Modo mais lento. Modo orientado a datagrama (UDP/IP): Não há garantia de entrega das mensagens; Ordem das mensagens pode ser perdida; Cada mensagem é um pacote que contém o remetente, o destinatário e o conteúdo (datagrama); Muito mais rápido que o modo orientado a conexão. Sockets Sockets são mecanismos de comunicação entre processos, que podem estar em uma mesma máquina ou em diferentes computadores em uma rede. Modo orientado a conexão TCP/IP Como funciona: O servidor abre uma porta e fica aguardando conexões; O cliente deve saber previamente o endereço do servidor (IP) ou seu nome (hostname) e a porta; O cliente solicita uma conexão. Se nenhum problema ocorrer, o servidor aceita a conexão, gerando um socket em outra porta qualquer do seu lado, que é o canal de comunicação entre o cliente e o servidor. Em Java, a comunicação através de sockets utiliza duas classes: Socket (soquete de dados) e ServerSocket (soquete do servidor). ServerSocket Construtor: ServerSocket(int port) – cria o socket especificando a porta Alguns métodos importantes: accept() – aguarda uma conexão, retornando um objeto da classe Socket, que representa a conexão estabelecida; close() – fecha a conexão; isClosed() – indica se o socket está fechado; getInetAddress() – retorna o endereço do servidor através de um objeto da classe InetAddress. Socket Construtor: Socket(InetAddress address, int port) – cria um socket conectando a um servidor em uma porta especificada; Socket(String host, int port) – idem anterior, porém o nome ou endereço do servidor é passado por uma String. Alguns métodos importantes: close() getInetAddress() getInputStream() – stream de dados de entrada getOutputStream() – stream de dados de saída Processo orientado a conexão Servidor ServerSocket(p) accept() InputStream/ OutputStream Troca de dados Cliente Socket(s,p) OutputStream/ InputStream Exemplo ExemploSocket Processo orientado a conexão O problema da comunicação orientada a conexão é que sempre um dos lados deve ficar aguardando, podendo manter o programa travado; Pode-se resolver esse problema de duas formas: Usando modo de comunicação orientado a datagramas (UDP); Utilizar threads para manter o programa funcionando enquanto aguarda a recepção de dados. Threads Threads, também chamadas de processos leves, permitem a execução em paralelo de múltiplas atividades em um mesmo processo; Java é a primeira linguagem de programação a incluir o conceito de threads na própria linguagem. Algumas razões para o uso de threads: Maior desempenho em sistemas multiprocessados; Funcionalidade em ambientes gráficos; Simplificação da modelagem em algumas aplicações. Threads Para implementar threads em Java, pode-se: Utilizar herança, criando uma subclasse da classe Thread; Implementar a interface Runnable. Basicamente, o mais importante nestes casos é a implementação do método public void run() e sua ativação pelo método start() Uma thread pode estar em um entre quatro estados: Nova (new); Executando (run); Suspensa (sleep); Encerrada (stop) Exemplo ExemploSocketThread Modo orientado a datagramas (UDP/IP) Sockets UDP/IP são mais rápidos que TCP/IP pois não exigem o estabelecimento de conexão; A comunicação ocorre pelo envio de mensagens, que são formadas por um datagrama, contendo o remetente (sender), destinatário (receiver) e o conteúdo (content); Caso o destinatário não “capture” a mensagem (não esteja aguardando por ela), a mesma é perdida; Em Java, a comunicação é feita através das classes DatagramSocket e DatagramPacket. DatagramSocket Construtor: DatagramSocket() – cria um socket de datagrama DatagramSocket(int port) – cria o socket especificando a porta para receber pacotes Alguns métodos importantes: close() – fecha o socket; getLocalPort() – retorna a porta usada para envio e recepção; receive(DatagramPacket p) – aguarda recepção de pacote; send(DatagramPacket p) – envia pacote. DatagramPacket Construtor: DatagramPacket(byte ibuf[], int ilength) DatagramPacket(byte ibuf[], int ilength, InetAddress iaddr, int iport) Alguns métodos importantes: getAddress() – retorna o endereço remoto (de quem recebeu ou para quem vai enviar); getData() – retorna o conteúdo do datagrama; getLength() – retorna o tamanho, em bytes, dos dados; getPort() – retorna a porta remota.