Buscar

Algoritmos e Lógica de Programação - Programação de Redes de Computadores (1)

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 6 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 6 páginas

Prévia do material em texto

Introdução às Redes de Computadores / 
Programação com sockets 
 
https://pt.wikiversity.org/wiki/Introdu%C3%A7%C3%A3o_%C3%A0s_Redes_de_Computado
res/Programa%C3%A7%C3%A3o_com_sockets 
 
Inicialmente precisa conceituar o que é socket. A comunicação entre processos 
de software tornou-se indispensável nos sistemas atuais. 
O elo entre os processos do servidor e do cliente é o socket. Ele é a “porta” na 
qual os processos enviam e recebem mensagens. De acordo com JAMES F 
KUROSE: “socket é a interface entre a camada de aplicação e a de transporte 
dentro de uma máquina”. 
Então foram desenvolvidas diversas aplicações cliente/servidor onde cliente(s) 
e servidor poderiam estar em máquinas diferentes, distantes umas das outras. 
Os aplicativos do cliente e do servidor utilizam protocolos de transporte para se 
comunicarem. Quando um aplicativo interage com o software de protocolo, ele 
deve especificar detalhes, como por exemplo se é um servidor ou um cliente. 
Além disso, os aplicativos que se comunicam devem especificar detalhes 
adicionais (por exemplo, o remetente deve especificar os dados a serem 
enviados, e o receptor deve especificar onde os dados recebidos devem ser 
colocados). 
Analisando o esquema acima percebemos que tudo acima da interface do 
socket, na camada de aplicação, é controlado pelo criador da aplicação. O 
controle da camada de transporte é feito pelo Sistema Operacional. 
Temos dois tipos de serviços de transporte via socket: o confiável orientado a 
cadeia de bytes (byte steam) e os datagramas não confiáveis. O protocolo na 
qual é implementado o primeiro é o TCP, já o segundo é implementado no 
protocolo UDP. 
Histórico 
Na década de 1980 nos Estados Unidos a ARPA (Advanced Research Projects 
Agency of the Department of Defense) deu à Berkeley, Universidade da 
California a responsabilidade de construir um sistema operacional que pudesse 
ser utilizado no suporte à ARPAnet, que é o antecessor da internet atual. 
Neste sentido, foi desenvolvida, com uma fonte genuina uma interface e 
adicionada ao sistema operacional, Unix BSD (Berkeley Software Distribution). 
Tal interface tinha justamente a função de suporte a comunicação em rede. Esta 
interface ficou então conhecida como Berkeley Sockets Interface, e é a base 
para a maioria das interfaces entre protocolos de internet TCP/IP existente. 
Existe uma nomenclatura específica para se referir a cada “lado” da 
comunicação. Temos o servidor, que fica esperando por conexões de entrada e 
que fornece certos tipos de serviços à outra parte. Já o Cliente vem a ser quem 
solicita a conexão ao servidor para fazer alguma requisição, algum pedido. É 
importante dizer que não é o computador que distingue quem é servidor e quem 
https://pt.wikiversity.org/wiki/Introdu%C3%A7%C3%A3o_%C3%A0s_Redes_de_Computadores/Programa%C3%A7%C3%A3o_com_sockets
https://pt.wikiversity.org/wiki/Introdu%C3%A7%C3%A3o_%C3%A0s_Redes_de_Computadores/Programa%C3%A7%C3%A3o_com_sockets
é cliente, mas sim a forma como certo programa usa os sockets. Às vezes 
também se faz confusão no fato de se pensar que um servidor precisa ser um 
mainframe. Desktops como os que usamos em casa funcionam tanto como 
cliente quanto como servidor, e é o que ocorre freqüentemente. 
Cada socket tem um endereço único na internet. Este endereço é formado por 
um número IP e por um número de porta. Devido às grandes dimensões da 
internet, não há como uma pessoa, ou mesmo uma máquina, saber o endereço 
de todas as outras. Para resolver este problema foi criado protocolo DNS 
(Domain Name Service). Este protocolo tem a função de traduzir os nomes ou 
endereços de alto nível das máquinas para o seu respectivo número IP. Assim, 
ao se passar o endereço de um socket de um servidor, não se passa diretamente 
seu número IP, mas sim um nome mais fácil de recordar e então o DNS traduz 
para o endereço real, ou endereço IP. 
Os sockets podem ser usados para comunicação via qualquer um dos protocolos 
UDP ou TCP. Assim, é possível termos tanto comunicação orientada a conexão 
(via TCP), quanta não orientada a conexão (via UDP). O socket abstrai esse 
conceito, permitindo assim a utilização de qualquer um dos meios. 
Programação de aplicações TCP 
Inicialmente o cliente deve contactar o servidor. Para isso, o processo servidor 
já deve estar executando o programa antes de ser contactado além de já ter 
criado o socket (porta) que aceita o contato do cliente. O cliente contacta o 
servidor criando um socket TCP local e especifica o endereço IP e o número da 
porta do processo servidor. Quando o servidor é contactado o servidor cria um 
novo socket para se comunicar com o cliente, permitindo assim a liberação do 
socket de “boas-vindas” para que possa ser contactado por outros clientes. 
Abaixo temos uma ilustracão: 
Ficheiro:Socket tcp.JPG 
Do ponto de vista da aplicação, a conexão TCP é um fluxo cotínuo de dados, a 
mensagem é fragmentada em pacotes, não há duplicação, ele garante a entrega 
e a ordem dos pacotes. A conexão é ponto-a-ponto: um remetente e um 
destinátario conectado por sockets. 
Abaixo é ilustrado uma aplicação cliente-servidor em Java: 
Ficheiro:Cliente servidor tcp java.JPG 
Este texto não tem como objetivo o aprendizado da linguagem Java, portanto só 
serão demonstradas e explicadas as linhas de códigos referentes às instruções 
que são utilizadas no programa exemplificado pela ilustração acima. 
Começando com a aplicação que será hospedada no Servidor. 
No início do programa, deverá ser inserida essas linhas que importam a 
biblioteca que contém as classes que são utilizadas em uma aplicação com 
Socket(java.net.*) e as classes de recepção de informação do teclado ou Socket 
do cliente ou servidor(java.io.*). 
 import java.net.*; 
https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=pt&wpDestFile=Socket_tcp.JPG
https://commons.wikimedia.org/wiki/Special:UploadWizard?uselang=pt&wpDestFile=Cliente_servidor_tcp_java.JPG
Aqui criamos um objeto welcomeSocket é o socket do lado do servidor, 
numero_da_porta deverá ser substituido pelo número da porta pela qual a 
aplicação cliente usará para conectar com o servidor. Este socket esperará a 
requisição de conexão de um cliente. 
 ServerSocket welcomeSocket = new ServerSocket(numero_da_porta); 
Como o programa servidor normalmente fica funcionando por tempo indefinido, 
coloca-se o restante das instruções dentro de um loop infinito, como segue: 
 
 while(true) { 
 ... 
 } 
A próxima instrução cria um objeto connectionSocket do tipo Socket quando um 
cliente conectar ao servidor. O TCP encarregará de criar uma conexão virtual 
direta entre esse socket e o socket do cliente de forma que todos os bytes serão 
enviados ao servidor na ordem certa. 
 Socket connectionSocket = welcomeSocket.accept(); 
No caso do envio de um objeto do tipo String do cliente para o servidor, utilizamos 
as seguintes instruções para receber os dados do cliente. 
 
 BufferedReader infoDoCliente = new BufferedReader(new 
InputStreamReader(connectionSocket.getInputStream()); 
 String mensagemDoCliente = infoDoCliente.readLine(); 
Depois de processar a informação enviada pelo cliente, queremos enviar um 
outro objeto(mensagem_para_cliente) do tipo String de volta para o cliente, 
como um mensagem de dado recebido ou algo do tipo. 
 DataOutputStream infoParaCliente = new 
DataOutputStream(connectionSocket.getOutputStream()); 
 infoParaCliente.writeBytes(mensagem_para_cliente); 
Com isso termina-se o programa do lado do Servidor. Agora analisaremos o 
programa cliente. 
Como no caso do programa servidor, o código inicia com a importação das 
bibliotecas que contém as classes de sockets e de envio de informações. 
 import java.io.*; 
 import java.net.*; 
Primeiramente, criamos o socket que conectará com o servidor. O primeiro 
parâmetro passado ao construtor é o nome do servidor, por exemplo, 127.0.0.1 
se a aplicação servidor estiver rodando no mesmo computador que a aplicaçãocliente. O segundo parâmetro é o número da porta que é informado ao socket 
servidor. 
 Socket clientSocket = new Socket("nome_do_servidor", 
numero_da_porta); 
Após a criação do socket cliente, temos que criar os objetos de cadeia que serão 
ligados ao socket. O objeto infoParaServidor será a cadeia que enviará 
informações para o servidor e o objeto infoDoServidor será a cadeia que 
receberá informações do servidor. 
 DataOutputStream infoParaServidor = new 
DataOutputStream(clientSocket.getOutputStream()); 
 BufferedReader infoDoServidor = new BufferedReader(new 
InputStreamReader(clientSocket.getInputStream())); 
Utilizaremos o mesmo caso do servidor, e enviaremos(mensagem_do_cliente) e 
receberemos(mensagem_para_cliente) dois objetos do tipo String para 
exemplificar. 
 infoParaServidor.writeBytes(mensagem_do_cliente); 
 String mensagem_para_cliente = infoDoServidor.readLine(); 
Agora já podemos fechar o socket, e também a conexão TCP entre cliente e 
servidor. 
 clientSocket.close(); 
Sockets UDP são mais rápidos que sockets TCP; São mais simples, porém 
menos confiável; Em UDP não é necessário abrir conexão, deste modo a 
comunicação ocorre apenas com o envio da mensagem; Um mensagem é um 
datagrama, que é composto de um remetente (sender) e um receptor (receiver) 
e a mensagem (content). 
Programação de sockets com UDP 
A comunicação entre processos também é possível por UDP. Entretanto, UDP é 
um serviço sem conexão. Com isso, não há o three-way handshaking (ou 
apresentação de três vias)inicial, e assim não há um canal pré-estabelecido entre 
os processos. Para que a comunicação entre os processos seja possível, deve-
se incorporar ao conjunto de bytes enviados tanto o endereço IP do destino 
quanto a porta do processo de destino. Este conjunto (bytes + endereço IP + 
porta) recebe o nome de pacote. 
Com o pacote criado, ele é colocado na rede através do socket. O processo 
receptor deverá abrir o pacote para retirar as informações pertinentes. Sendo o 
UDP um serviço sem conexão, não há garantias de que o pacote realmente 
chegará ao seu destino. 
Na comunicação por TCP, não é necessário que todas as cadeias de bytes 
recebam endereço IP e número de porta, já que existe uma tubulação virtual, 
pela qual as cadeias fluem, que possui estas informações adicionais. Já na 
comunicação por UDP, não havendo esta tubulação virtual, torna-se necessário 
que as cadeias de bytes sejam organizados em pacotes, todos com endereço IP 
e número de porta. 
Abaixo segue uma exemplo de programação em socket com UDP. Assim como 
dito anteriormente, o objetivo aqui não é ensinar java, mas sim exemplificar 
programação com sockets. Comecemos pela parte do servidor. 
 DatagramSocket serverSocket = new DatagramSocket(9876); 
Diferentemente do TCP, aqui criamos um objeto do tipo DatagramSocket e não 
ServerSocket. Os dados que serão enviados e recebidos pelo servidor passarão 
todos através deste socket do tipo DatagramSocket. Não se faz necessário a 
criação de um objeto DatagramSocket para cada nova conexão. Todas as 
conexões dos clientes passarão por esse único socket serverSocket. Isto não é 
um problema porque cada vez que recebe um pacote, o servidor responde e fica 
livre novamente, pois inexiste conexão entre ambos. O socket escuta na porta 
9876. 
 while (true) { ... } 
Loop infinito, onde o servidor fica esperando o recebimento de pacotes. 
 DatagramPacket receivePacket = new DatagramPacket(receiveData, 
receiveData.length); 
 serverSocket.receive(receivePacket); 
O objeto receivePacket aloca memória onde serão salvos os dados de entrada, 
recebidos pelo servidor. O método receive fica esperando o recebimento e 
armazena o pacote em receivePacket. 
 String sentence = new String(receivePacket.getData()); 
 InetAddress IPAdress = receivePacket.getAddress(); 
 int port = receivePacket.getPort(); 
Estas linhas desmontam o pacote, retirando informações necessárias à 
retransmissão. O objeto sentence recebe os dados. IPAdress é o número de IP 
do cliente, que é necessário para mandar a resposta assim como o número de 
porta port. Todos estes dados foram enviados pelo cliente. Após o 
processamento a resposta é enviada para o respectivo endereço IP e número de 
porta. 
Do lado do cliente temos a criação do socket pelo qual será enviado um pacote 
da seguinte forma: 
 DatagramSocket clientSocket = new DatagramSocket(); 
Note que a única diferença entre o socket cliente e o servidor é de que para o 
servidor foi necessário especificar um número de porta, e para o cliente não. 
Este comando não cria conexão alguma e nem contata o servidor, e é justamente 
por isso que não se faz necessário especificar nome do servidor nem seu numero 
de porta. 
 InetAddress IPAddress = InetAddress.getByName(“hostname”); 
Aqui criamos um objeto para armazenar o número de IP do Server. Hostname é 
o nome (apelido) do servidor. O método getByName() faz uma consulta ao 
servidor DNS para saber qual o número IP do server. 
 byte[] sendData new byte[1024]; 
 byte[] receiveData = new byte[1024]; 
Estes dois vetores armazenarão os dados enviados e recebidos 
respectivamente. 
 DatagramPacket sendPacket = new DatagramPacket(sendData, 
sendData.length, IPAdress, 9876); 
Esta linha cria o pacote que será enviado ao Server. Nele estão gravados os 
dados em si, sendData, o tamanho dos dados, sendData.length, o número de IP 
do Server, IPAdress, e o número da porta onde o Server espera, 9876. 
 clientSocket.send(sendPacket); 
Depois de pronto, enviamos o pacote através do método send do socket 
clientSocket. Enviado o pacote o cliente fica esperando uma resposta. 
 clientSocket.receive(receivePacket); 
Quando ocorre o recebimento do pacote, ele é armazenado em receivePacket.

Continue navegando