Implementando comunicação em JAVA via Sockets Alcides Calsavara - [email protected] Leonardo R. Nunes - [email protected] Sockets Utilizado para comunicação entre processos; Compreendendo Sockets Sockets Mecanismo básico de comunicação sobre IP Fornece três modos de acesso: Modo orientado a conexão (connection-oriented): Socket, ServerSocket; Modo orientado a datagrama (datagram-oriented): DatagramSocket, MulticastSocket; Acesso a dados IP de baixo nível (raw ip data): SocketImpl Modo orientado a conexão (connection-oriented) Funciona sobre o protocolo TCP/IP Serviços confiáveis: Sem perdas de dados na rede; Garantia de ordem dos pacotes; “Data streams” podem ser utilizados Desvantagens: É mais lento que o modo orientado a datagrama; Comportamento servidor diferente do comportamento cliente; Ações para implementar um socket cliente 1 - Abrir a conexão: import java.io.* ; // streams import java.net.* ; // sockets Socket clientSocket = new Socket (“www.javasoft.com”, 80); Ações para implementar um socket cliente 2 - Pegando os streams de entrada e saída: DataInputStream inbound = new DataInputStream ( clientSocket.getInputStream( ) ); DataOutputStream outbound = new DataOutputStream ( clientSocket.getOutputStream( ) ); Ações para implementar um socket cliente 3 - Utilizando os streams de entrada e saída: outbound.writeInt( 3 ); outbound.writeUTF( “Hello” ); int k = inbound.readInt( ); String s = inbound.readUTF() ; Ações para implementar um socket cliente 4 – Fechando os streams de entrada e saída: inbound.close () ; outbound.close () ; 5 – Fechando o socket: clientSocket.close() ; Ações para implementar um socket servidor 1 - Criar o server socket: ServerSocket serverSocket = new ServerSocket (80, 5); 2 - Aguardar conexoes de clientes: Socket clientSocket = serverSocket.accept (); Ações para implementar um socket servidor 3 - Criar streams de entrada e saída do cliente: DataInputStream inbound = new DataInputStream ( clientSocket.getInputStream( ) ) ; DataOutputStream outbound = new DataOutputStream ( clientSocket.getOutputStream( ) ) ; Ações para implementar um socket servidor 4 - Conversando com o cliente: int k = inbound.readInt( ); String s = inbound.readUTF() ; outbound.writeInt( 3 ); outbound.writeUTF( “Hello” ); Ações para implementar um socket servidor 5 - Fechando streams e socket cliente: inbound.close () ; outbound.close () ; clientSocket.close() ; 6 - Fechando o socket servidor: serverSocket.close() ; Modo orientado a conexão - features Possibilidade de sockets unidirecional: socket.shutdownInput(); socket.shutdownOutput(); Implementações de alto nível para protocolos como http, etc... Modo orientado a datagrama (datagram-oriented) Funciona sobre o protocolo UDP/IP Serviços não confiáveis: Mensagens podem ser perdidas; Ordem das mensagens não garantida; Cada mensagem é um datagrama: [sender, receiver, contents] Vantagem: É muito mais rápido que o modo orientado a conexão; Utilizando datagramas (sender side) 1 - Criação do socket cliente: // sender socket doesn’t need // a special port number DatagramSocket clientSocket = new DatagramSocket () ; Utilizando datagramas (sender side) 2 - Criando e enviando o datagrama: InetAddress addr=InetAddress.getByName (“www.javasoft.com”) ; String toSend = “That’s my question!” ; byte[] buffer = toSend.getBytes() ; // datagram to receiver’s port 4545 DatagramPacket question = new DatagramPacket (buffer, buffer.length, addr, 4545) ; clientSocket.send (question) ; Utilizando datagramas (sender side) 3 - Recebendo e abrindo uma resposta: DatagramPacket answer = new DatagramPacket (new byte[512], 512); clientSocket.receive (answer) ; System.out.println (answer.getData() + “\n” + answer.getLength() + “\n” + answer.getAddress() + “\n” + answer.getPort() ) ; Utilizando datagramas (sender side) 4 - Fechando o socket clientSocket.close() ; Utilizando datagramas (receiver side) 1 - Criando um socket servidor: // listens on port 4545 DatagramSocket serverSocket = new DatagramSocket (4545) ; Utilizando datagramas (receiver side) 2 - Recebendo um datagrama: DatagramPacket question = new DatagramPacket (new byte[512], 512) ; serverSocket.receive (question) ; Utilizando datagramas (receiver side) 3 - Enviando o datagrama resposta: String toSend = “That’s the answer !” ; byte[] buffer = toSend.getBytes() ; DatagramPacket answer = new DatagramPacket (buffer, buffer.length, question.getAddress()/*sender info*/, question.getPort()/*sender info*/); serverSocket.send (answer) ; Utilizando datagramas (receiver side) 4 - Fechando o socket servidor: serverSocket.close() ; Modo orientado a datagama – Multicast Um grupo “Multicast” é especificado por um endereço IP de classe “D” (224.0.0.0 até 239.255.255.255, inclusive) e uma porta UDP. O endereço 224.0.0.0 é reservado e não deve ser usado. MulticastSocket: InetAddress group = InetAddress.getByName("228.5.6.7"); MulticastSocket s = new MulticastSocket(6789); s.joinGroup(group); // Envia e recebe mensagens. s.leaveGroup(group); Sockets sobre IP - TCP e UDP Algumas configurações: Timeout do Sistema Operacional; Utilização de buffers; KeepAlive; etc ... Acesso a dados IP de baixo nível Java possibilita acesso a algumas configurações ip, mas não permite raw sockets. SocketImplFactory SocketImpl SocketOptions