terça-feira, 14 de agosto de 2012

RE: RES: RES: [java-br] Socket

·

4 ) package Cliente;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
public class ClienteSocket{ private Socket conexao; public ClienteSocket(Socket socket) {
this.conexao = socket;
}
public static void main(String args[])
{
try {

Socket socket = new Socket("127.0.0.1", 5555);

PrintStream saida = new PrintStream(socket.getOutputStream());
BufferedReader teclado = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Digite seu nome: ");

saida.println(teclado.readLine());

//----------- esta thread fica responsavel por receber mensagens
Thread usuario = new UsuarioCliente(socket);
usuario.start(); //----------- e o programa principal para enviar mensagens while (true) {
saida.println(teclado.readLine());
}

} catch (IOException e) { System.out.println("Falha");}
}} package Cliente;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class UsuarioCliente extends Thread{

Socket conexao;

UsuarioCliente(Socket conexao){

this.conexao = conexao;
} public void run()
{
try {

//--pega o input do programa principal que chamou a thread
BufferedReader entrada = new BufferedReader(new InputStreamReader(this.conexao.getInputStream())); String msg;
while (true){
msg = entrada.readLine(); System.out.println(msg);
}
} catch (IOException e) { System.out.println("Falha"); }
} isso ai é um exemplo de chat simples desconsidere todo o resto, veja apenas 2 detalhes: eu tenho a thread principal com um while(true) e então crio uma thread secundária onde o código é o de baixo, que também possuí um while(true), a do principal vai enviar as mensagens e a outra vai receber. ao invés de (true) acho que você pode usar: (socket.isConnected()). a thread secundária seria algum tipo de confirmação do envio. ~-------------------
To: java-br@yahoogrupos.com.br
From: lvctecno@yahoo.com.br
Date: Tue, 14 Aug 2012 14:57:14 -0300
Subject: RES: RES: [java-br] Socket


























Boa Douglas, brigadão pelas dicas, vamos lá:



Pelo que entendi, então não estou cometendo nenhum grande sacrilégio.



1 - implementar após o accept(), um sistema de login e senha....

R. por enquanto não estou preocupado com a segurança dos dados, somente com

a rapidez e confiabilidade.



2 - separe um pouco as classes, faça o tratamento dos dados assim que

receber a informação, quanto menos Ifs melhor

R. bom eu separei uma que recebe e outra que envia, vc quis dizer tipo não

criar um procedimento e sim fazer direto no IF?



3 - fazer testes de stress, coloque um while(1<1000) na classe (cliente)

para se conectar 1000x e ler/escrever 1000 no socket, depois faça outro

teste, 1000 conexões e 100.000 ler/escrever no socket, de acordo com a dica

abaixo(4)........... veja o tempo que demorou e quanto consumiu de

memoria.....acompanhe o processamento e banda do servidor

R. vou fazer.



4 - quando um cliente realiza conexão é criada uma nova thread para esse

cliente, ai ele envia as informações e desconecta...eu acho que nesse caso é

legal você manter a conexão ativa, segurando uma thread la na classe do

cliente, por exemplo, se conectou...vai enviando informações a vontade, se

alguma tentativa falhar, conecta novamente.

R. Teria como vc me dar um exemplo?



5 - trate as exceções com carinho, de inicio tudo bem você vai dando

exception e descobrindo onde esta os maiores problemas, mais depois com o

tempo, tente tratar as exceções antes delas ocorrerem, para minimizar erros

nos clientes. (que seja com ifs)

R. só ocorre um erro, e no servidor, que é o deadlock, quando dois aparelhos

tentam utilizar o mesmo procedimento. Nos aparelhos não dão boca.



6 - de acordo com a dica acima(5), se pelo que eu entendi, eu tenho um GPS e

falhou vai dar erro e ja era...ai é problema, por que erros vão ter....você

vai ter que ter uma tolerancia a esses erros, por exemplo se eu recebi a

requisição agora: 20s e não recebi a de 40s, você pode ter um Log e

marca-lo, porém sem deixar de funcionar o cliente...

R. quanto a isso tah tranquilo.



O Marcelo me deu um bizu muito legal sobre nios, não blocante, que seria

capaz de receber zilhoes de requisições sem dar pau.



Achei um exemplo assim, enviando a hora do servidor:



Selector acceptSelector = SelectorProvider.provider().openSelector();

ServerSocketChannel ssc = ServerSocketChannel.open();

ssc.configureBlocking(false);

InetAddress lh = InetAddress.getLocalHost();

InetSocketAddress isa = new InetSocketAddress(lh, PORTA_UTILIZADA);

ssc.socket().bind(isa);

SelectionKey acceptKey = ssc.register(acceptSelector,

SelectionKey.OP_ACCEPT);

int keysAdded = 0;



while ((keysAdded = acceptSelector.select()) > 0) {

Set readyKeys = acceptSelector.selectedKeys();

Iterator i = readyKeys.iterator();

while (i.hasNext()) {

SelectionKey sk = (SelectionKey)i.next();

i.remove();

ServerSocketChannel nextReady =

(ServerSocketChannel)sk.channel();

Socket s = nextReady.accept().socket();



//AQUI ELE DEVOLVE A DATA DO SERVIDOR

PrintWriter pw = new PrintWriter(s.getOutputStream(),

true);

Date now = new Date();

pw.println(now);

pw.close();

}

}



Só que neste exemplo ele não separou nada, tá tudo junto e pronto para

receber uma requisição especifica, no caso a hora do servidor, como faria

para dizer neste exemplo o que quero requisitar e o que ele deve me

responder?



[]'s

Luciano



-----Mensagem original-----

De: java-br@yahoogrupos.com.br [mailto:java-br@yahoogrupos.com.br] Em nome

de Douglas Nogueira

Enviada em: terça-feira, 14 de agosto de 2012 13:47

Para: java-br@yahoogrupos.com.br

Assunto: RE: RES: [java-br] Socket



olha, acho que você deve implementar mais coisas ai que são "quase

essenciais": 1 - implementar após o accept(), um sistema de login e

senha.... 2 - separe um pouco as classes, faça o tratamento dos dados assim

que receber a informação, quanto menos Ifs melhor 3 - fazer testes de

stress, coloque um while(1<1000) na classe (cliente) para se conectar 1000x

e ler/escrever 1000 no socket, depois faça outro teste, 1000 conexões e

100.000 ler/escrever no socket, de acordo com a dica abaixo(4)...........

veja o tempo que demorou e quanto consumiu de memoria.....acompanhe o

processamento e banda do servidor 4 - quando um cliente realiza conexão é

criada uma nova thread para esse cliente, ai ele envia as informações e

desconecta...eu acho que nesse caso é legal você manter a conexão ativa,

segurando uma thread la na classe do cliente, por exemplo, se conectou...vai

enviando informações a vontade, se alguma tentativa falhar, conecta

novamente. 5 - trate as exceções com carinho, de inicio tudo bem você vai

dando exception e descobrindo onde esta os maiores problemas, mais depois

com o tempo, tente tratar as exceções antes delas ocorrerem, para minimizar

erros nos clientes. (que seja com ifs) 6 - de acordo com a dica acima(5), se

pelo que eu entendi, eu tenho um GPS e falhou vai dar erro e ja era...ai é

problema, por que erros vão ter....você vai ter que ter uma tolerancia a

esses erros, por exemplo se eu recebi a requisição agora: 20s e não recebi a

de 40s, você pode ter um Log e marca-lo, porém sem deixar de funcionar o

cliente... qualquer dúvida estamos ai To: java-br@yahoogrupos.com.br

From: lvctecno@yahoo.com.br

Date: Tue, 14 Aug 2012 12:13:49 -0300

Subject: RES: [java-br] Socket



Ola Marcelo obrigado pelo interesse na ajuda.



Deixa eu te passar o cenário do problema:



Tenho um aplicativo rodando em Android que se comunica através de HTTP



(paginas jsp) com servidor Tomcat, trabalho com sistemas de rastreamento



cada aparelho me envia de 60 em 60 segundos sua id e localização.



Cada aparelho faz em media 5 requisições por minuto, incluso o envio de



localização, ae tu multiplica isso por 100 aparelhos e vamos chegar na casa



das 500 requisições por minuto, o que as paginas estão dando conta sem



problemas.



O meu problema está no consumo, pois cada requisição hoje, me enviando 0 ou



1 ou nada, consome no aparelho 1Kb, quando percebi que via socket consome



somente 1k, ou seja 1023k a menos.



Consegui depois de muito penar na web, construir um servidor socket assim



(sei que devo estar fazendo altos sacrilégios, mas foi como consegui chegar



e até então meu conhecimento em sockets era abaixo de zero) :



Na classe principal:



public static void main(String[] args) throws IOException {



ServerSocket serverSocket = new ServerSocket(PORTA);



System.out.println("INICIADO");



while(true){



Socket socket = serverSocket.accept();



new ServicoThread(socket).start();



}



}



Na classe Serviço:



public class ServicoThread extends Thread {



private final Socket socket;



public ServicoThread(Socket socket) {



this.socket = socket;



}



@Override public void run() {



try {



DataInputStream in = new



DataInputStream(socket.getInputStream());



DataOutputStream out = new



DataOutputStream(socket.getOutputStream());



ExecutaServico es = new ExecutaServico(in);



es.enviar(out);



out.close();



in.close();



socket.close();



} catch (IOException e) {



e.printStackTrace();



}



}



}



Na classe executora assim:



public ExecutaServico(DataInputStream in) {



String nomeServico = "";



try {



this.servico = DataInputStream.readUTF(in).toString().trim();



if(servico.trim().equals("02")){



nomeServico = "LOCALIZACAO";



this.id = DataInputStream.readUTF(in);



this.latitude = DataInputStream.readUTF(in);



this.longitude = DataInputStream.readUTF(in);



this.velocidade = DataInputStream.readUTF(in);



}



public void enviar(DataOutputStream out) throws IOException{



if (this.servico.equals("02")) { //LOCALIZAÇÃO



int i = cadastrarPosicao();



if(i > 0){



out.writeUTF("1");



} else {



out.writeUTF("0");



}



}



public synchronized int cadastrarPosicao(){



int i = 0;



try {



cs = bd.conectar().prepareCall("{call



qry_001(?,?,?,?)}");



cs.setString(1, id);



cs.setString(2, latitude);



cs.setString(3, longitude);



cs.setString(4, velocidade);



i = cs.executeUpdate();



} catch (SQLException ex) {



ex.printStackTrace();



} finally {



try {



if (cs != null){



cs.close();



cs = null;



}



} catch (SQLException c){ }



bd.desconectar();



}



return i;



}



Bom via de regra geral funciona, mas não tenho coragem de colocar em



produção, porque não estou acreditando que este dará conta da quantidade de



requisições, com apenas dois aparelhos em laboratório, a quantidade de



deadlocks é pequena, mas existe, mas com um grande quantidade acredito que



vá explodir.



Se vc puder me ajudar a enquadrar isso que eu fiz até aqui, na maneira como



vc descreveu e conseguirmos montar alguma coisa que responda a uma grande



quantidade de requisições, a gente tenta encarar.



Fique a vontade se quiser me adicionar no MSN.



De antemão muito obrigado pelas informações, cara valeu.



Luciano



De: java-br@yahoogrupos.com.br [mailto:java-br@yahoogrupos.com.br] Em nome



de MarceloMF



Enviada em: terça-feira, 14 de agosto de 2012 11:01



Para: java-br@yahoogrupos.com.br



Assunto: Re: [java-br] Socket



Olá Luciano,



O protocolo http roda em cima do protocolo TCP, você provavelmente devera



escolher entre 2 protocolos:



TCP - Estabelece conexão, realiza o 3way handshake:



PC1 -------------->(SYN) PC2 (Primeiro pacote solicitando conexão)



PC2 ----->(SYN+ACK) PC1 (Segundo pacote confirmando o recebimento do



primeiro)



PC1 -------------->(ACK) PC2 (Terceiro pacote confirmando o recebimento do



segundo e estabelecendo a conexão)



UDP - Não estabelece conexão, não realiza o 3way handshake, por isso é



utilizado para funcionalidades como streeming.



Então é provável que você utilize o TCP, dessa forma você devera criar um



protocolo para trafegar suas informações, normalmente ele se divida em 2



partes:



header -> Informações gerais sobre o pacote/mensagem



payload -> Conteúdo do pacote/mensagem



Exemplo de header:



NOME_TRANSACAO(10POSICOES C/ " " A ESQUERDA)+TAMANHO_PAYLOAD(10POSICOES C/



0 A ESQUERDA)+PAYLOAD(VARIÁVEL)+HASH_PACOTE(64 POSIÇÕES)



Exemplo de payload:



NOME_INFORMACAO1(10POSIÇÕES C/ " " A



ESQUERDA)+TAMANHO_INFORMACAO1(10POSIÇÕES C/ 0 A



ESQUERDA)+INFORMACAO1(VARIÁVEL)



+NOME_INFORMACAO2(10POSIÇÕES C/ " " A



ESQUERDA)+TAMANHO_INFORMACAO2(10POSIÇÕES C/ 0 A



ESQUERDA)+INFORMACAO2(VARIÁVEL)



+NOME_INFORMACAO3(10POSIÇÕES C/ " " A



ESQUERDA)+TAMANHO_INFORMACAO3(10POSIÇÕES C/ 0 A



ESQUERDA)+INFORMACAO3(VARIÁVEL)



O seu pacote:



HEADER+PAYLOAD



Perceba que os campos do header são fixo e que o payload é variável. Como



você define o tamanho do payload e o tamanho de cada informação dentro do



payload, é possível realizar o parser da string tranquilamente.



Não sei qual sua necessidade, mas considere utilizar webservices, seja



rest, wsdl, ou mesmo JMS.



Depois de definido o layout do seu protocolo, virá a parte mais legal, que



é definir como o seu servidor irá processar essas mensagens.



Nesse ponto sugiro uma lida no livro Programação de rede Unix, Capitulo 30



-> Alternativas de projeto cliente/servidor, irei listar os tópicos, pois



sei que pode te ajudar.



30.4 - > Servidor TCP Interativo



30.5 -> Servidor TCP concorrente, um filho por cliente



30.6 -> Servidor TCP pré-bifurcado, sem bloqueio accept



30.7 -> Servidor TCP pré-bifurcado, bloqueio de arquivo em torno de accept



30.8 -> Servidor TCP pré-bifurcado, bloqueio de thread em torno de accept



30.9 -> Servidor TCP pré-bifurcado, passagem de descritor



30.10 -> Servidor TCP concorrente, um thread por cliente



30.11 -> Servidor TCP pré-threaded, um accept por thread



30.12 -> Servidor TCP pré-threaded, thread principal chama accept



Acima temos exemplos da utilização de forks e threads, no seu caso,



provável que utilize threads e definir como funcionara suas threads/pool de



threads será crucial para a escalabilidade da sua aplicação. Sugiro que



você abstraia a linguagem e se concentre nos conceitos... dessa forma você



irá conseguir desenvolver algo bacana.



O Java - Como programar do Deitel possui exemplos simples de como trabalhar



com sockets/threads, legal para fazer e ver funcionando, mas sinceramente



deixa a desejar e por isso recomendei o Programação de rede Unix como



literatura auxiliar.



Na mesma linha, você pode pesquisar sobre JAVA NIO(caso você possua *muitas



transações* concorrentes) e também se preocupar com a criptografia dos



pacotes... seja ela feita na camada de apresentação ssl/tls ou a nível de



aplicação, seja simétrica ou assimétrica.



Boa sorte! Inveja alheia... queria estar com um problema desses nas mãos



\o/.



[]s



--



Att, Marcelo M. Fleury



Blog - http://marcelomf.blogspot.com/



Slides - http://www.slideshare.net/marcelomf/



"O primeiro dever da inteligência é desconfiar dela mesma." By Einstein



[As partes desta mensagem que não continham texto foram removidas]



[As partes desta mensagem que não continham texto foram removidas]







[As partes desta mensagem que não continham texto foram removidas]



------------------------------------



Para sair da lista, envie email para: java-br-unsubscribe@yahoogroups.com

Para upload/download de arquivos:

http://www.yahoogroups.com/files/java-brLinks do Yahoo! Grupos


















[As partes desta mensagem que não continham texto foram removidas]



------------------------------------

Para sair da lista, envie email para: java-br-unsubscribe@yahoogroups.com
Para upload/download de arquivos: http://www.yahoogroups.com/files/java-brLinks do Yahoo! Grupos

<*> Para visitar o site do seu grupo na web, acesse:
http://br.groups.yahoo.com/group/java-br/

<*> Para sair deste grupo, envie um e-mail para:
java-br-unsubscribe@yahoogrupos.com.br

<*> O uso que você faz do Yahoo! Grupos está sujeito aos:
http://br.yahoo.com/info/utos.html

0 comentários:

Pague com LPs do Mister Colibri

Pague com LPs do Mister Colibri
Quer comprar celular,Tablet,pen drive, GPS e muito outros produtos e ainda podendo pagar tudo em LPs ?Pois saiba que isso é possível,basta você visitar o site downloadstotal.com e realizar a sua compra com toda tranquilidade e segurança!!!

Hora

Online

Arquivo do Blog