Olá a todos!
Estou implementando uma comunicação socket entre um site desenvolvido em java (Servidor) e uma aplicação Delphi (Cliente).
O servidor java está ok… recebe mensagens do cliente delphi sem problemas, porém, não estou conseguindo fazer com que o retorno do servidor chegue ao cliente. Segue abaixo trechos simplificados do código.
Estou utilizando Delphi 7 com o componente TClienteSocket, original do próprio delphi.
Qualquer sugestão será bem-vinda.
[]s
Juarez
public serverSocket() {
serverSocket = new ServerSocket(1000);
while (true) {
System.out.println(“Socket Server inicializado.”);
socket = serverSocket.accept();
System.out.println(“client conectado”);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
System.out.println(in.readLine()); // recebe mensagem do cliente. funciona corretamente
out.write(“msg de retorno ao cliente”); // nao funcionou. Não chega nada no socket do delphi 7
out.println(“msg de retorno ao cliente”); // nao funcionou. Não chega nada no socket do delphi 7
System.out.println(“Socket Server finalizado.”);
}
}
procedure TfrmCliente.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
Var x: String;
begin
showmessage(‘Chegou mensagem do socket servidor’);
…
…
Código para manipulação dos dados recebidos
…
…
end;
out.write("msg de retorno ao cliente"); // nao funcionou. Não chega nada no socket do delphi 7
out.println("msg de retorno ao cliente"); // nao funcionou. Não chega nada no socket do delphi 7
Isso desabilita o algoritmo de Nagle, do próprio TCP, que une pacotes pequenos num pacote maior. Esse algoritmo foi criado para evitar sobrecarga da rede caso aplicações que trabalhem com tinigrams (pacotes minúsculos), estejam operando. O Telnet, por exemplo, antes do algoritmo, enviava um pacote TCP por letra pressionada. E imagine uma rede inteira nos anos 70/80 com pessoas usando o telnet para comunicar com seu mainframe sem esse algoritmo…
out.write("msg de retorno ao cliente"); // nao funcionou. Não chega nada no socket do delphi 7
out.println("msg de retorno ao cliente"); // nao funcionou. Não chega nada no socket do delphi 7
[/quote]
Testei o out.flush(); mas, ainda está faltando alguma coisa… Continua não chegando o retorno do servidor(Java) para o cliente(Delphi) .
Valeu!!
Olá Ricardo!
Ainda estou em tempo de partir para outra solução… Pensei em webservice, mas, achei que seria mais rápido e fácil fazer com socket.
Vc acha que não é confiável utilizar socket nesse caso? Não funcionaria bem?
Valeu!!
Juarez
[/quote]
Não digo que socket não é confiável. Digo apenas que webservices já conta com frameworks dotados de uma certa segurança embutida e controle de acesso. Outro ponto a ser considerado é que algumas redes tem restrições a sockets puros, limitando o trafego em http/https apenas.
Quanto a rapidez do desenvolvimento, volto a recomendar um estudo do XFire e uma olhada no link demonstrando a facilidade de se consumir um webservice pelo Delphi 7.
[quote=juarezna]Testei o out.flush(); mas, ainda está faltando alguma coisa… Continua não chegando o retorno do servidor(Java) para o cliente(Delphi) .
Valeu!![/quote]
Juarezna, tenta usar o código que estou enviando, essa classe que ainda estou montando funciona tanto como cliente como servidor dependendo do construtor usado. Como ainda não terminei (e ainda não sei como resolver o problema) essa classe só responde a primeira conexão, se por acaso o cliente cair, é necessário reiniciar a aplicação para que volte a responder. Já deixei preparado pra responder a mensagem do mesmo jeito que receber. Alías, se conseguir resolver o problema das desconexões, me avisa!!!
import java.io.*;
import java.net.*;
public class Conexao extends Thread {
private ServerSocket serverSock;
private Socket clientSock;
private boolean tipoConex; //false=Servidor e true=Cliente
private String mensagem;
private InputStreamReader isr;
private OutputStreamWriter osw;
//Construtor para ser Servidor
public Conexao(int porta) {
super("Server");
try {
serverSock = new ServerSocket(porta);
tipoConex = false;
}
catch (IOException e) {
System.err.println("Erro: nao foi possivel criar o socket");
System.exit(1);
}
}
//Construtor para ser Cliente
public Conexao(String serverIP, int serverPort) {
try {
clientSock = new Socket(serverIP, serverPort);
isr = new InputStreamReader(clientSock.getInputStream());
osw = new OutputStreamWriter(clientSock.getOutputStream());
tipoConex = true;
}
catch (UnknownHostException e) {
System.err.println("Nao foi possivel conectar em " + serverIP);
System.exit(1);
}
catch (IOException e) {
System.err.println("Falha geral ao tentar conectar em " + serverIP);
System.exit(1);
}
}
public void run() {
if (tipoConex == false) {
// Procura por clientes
while (true) {
// Espera por cliente
if (serverSock == null) {
return;
}
try {
clientSock = serverSock.accept();
}
catch (IOException e) {
System.err.println("Erro: nao foi possivel conectar ao cliente");
System.exit(1);
}
// Processa requisicoes de cliente
try {
isr = new InputStreamReader(clientSock.getInputStream());
osw = new OutputStreamWriter(clientSock.getOutputStream());
while (true) {
String msgRecebida = "";
int tamanho = clientSock.getInputStream().available();
for (int counter = 0; counter < tamanho; counter++) {
msgRecebida += (char) isr.read();
}
if (tamanho != 0) {
mensagem = msgRecebida;
}
}
}
catch (Exception e) {
System.err.println("Error: " + e);
e.printStackTrace();
}
}
}
else {
while (true) {
try {
String msgRecebida = "";
int tamanho = clientSock.getInputStream().available();
for (int counter = 0; counter < tamanho; counter++) {
msgRecebida += (char) isr.read();
}
if (tamanho != 0) {
mensagem = msgRecebida;
}
}
catch (Exception e) {
System.err.println("Error: " + e);
e.printStackTrace();
}
}
}
}
public String getMensagem() {
if (mensagem != null) {
String msgRetorno = mensagem;
mensagem = null;
return msgRetorno;
}
return null;
}
public boolean enviaMensagem(String mensagem) {
try {
osw.write(mensagem);
osw.flush();
return true;
}
catch (Exception e) {
return false;
}
}
public static void main (String args[]){
Conexao c = new Conexao(5555);
c.start();
while (true){
try{
if (c.enviaMensagem(c.getMensagem())){
System.out.println("mensagem enviada com sucesso!");
}
}
catch(Exception e){
System.out.println("ooops deu erro");
}
}
}
}
[quote=ViniGodoy]Para pacotes pequenos, use também o comando:
socket.setTcpNoDelay(true);
Isso desabilita o algoritmo de Nagle, do próprio TCP, que une pacotes pequenos num pacote maior. Esse algoritmo foi criado para evitar sobrecarga da rede caso aplicações que trabalhem com tinigrams (pacotes minúsculos), estejam operando. O Telnet, por exemplo, antes do algoritmo, enviava um pacote TCP por letra pressionada. E imagine uma rede inteira nos anos 70/80 com pessoas usando o telnet para comunicar com seu mainframe sem esse algoritmo…[/quote]
Olá!! Testei também o comando, mas a mensagem continua não chegando ao Delphi:
procedure TfrmCliente.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
begin
showmessage(‘Chegou mensagem do socket servidor’);
end;
Tenta utilizar o PrintStream do java no lugar do OutputStreamWriter para ver no quê da.
PrintStream out = new PrintStream(this.socket.getOutputStream(),true,"UTF-8");
out.println("MENSAGEM PARA O CLIENTE");
out.flush();
Olha, no seu cliente você precisa colocar um estrutura parecida como abaixo para ele ficar verificando “eternamente” quando chega um mensagem. Se você simplesmente der um system.out no in.readLine() pode ser que nesse momento realmente não tenha nada a exibir. Dai é bom você olhar o código bergão.
Outro detalhe, e que para seu server java suportar mais de um cliente é necessário usar Threads.
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
String text;
while ((text = in.readLine())!=null) {
System.out.println("Mensagem:" + text);
}
Aproveitando o topico, gostaria de tirar um dúvida. É possível ter um servidor socket em um aplicativo .war rodando em um servidor de aplicação?