Como responder a um Socket

12 respostas
marciofermino

Amigos realmente não sei como implementar.
Mas o fabricante de um dispositivo me disse que preciso responder qualquer string assim que
alguem se conectar so socket do servidor;.

Seguindo código abaixo como poderia implementar :??

Obrigado;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TCPServer {
	private int serverPort = 2008;
	private ServerSocket serverSocket;
	private List<ConnectionService> connections = new ArrayList<ConnectionService>();

	
	int x=0;
	
	
	public TCPServer() {
		try {
			serverSocket = new ServerSocket(serverPort);
			System.out.println("Waiting...");
			
			while (true) {

					x++;
					
					
					Socket socket = serverSocket.accept();
	                System.out.println("Connected: " + socket);
	                ConnectionService service = new ConnectionService(socket);
	                service.start();

				
			}

		} catch (IOException e) {
			System.out.println("erro 1");
			//e.printStackTrace();
		}

	}

	public static void main(String[] args) {
		new TCPServer();
	}

	class ConnectionService extends Thread {

		private Socket socket;
		private BufferedReader inputReader;
		private PrintWriter outputWriter;

		// private String username;

		public ConnectionService(Socket socket) {
			this.socket = socket;
			
			System.out.println("Dados recebidos "+x);
			try {
				inputReader = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				outputWriter = new PrintWriter(socket.getOutputStream(), true);
				
				
			} catch (IOException e) {
				System.out.println("erro 2");
				//System.out.println(e.getMessage());
			}
		}

		@Override
		public void run() {
			while (true) {
				try {
					
						String receivedMessage = inputReader.readLine();
						
						
						if(receivedMessage!=null){
							System.out.println(receivedMessage+"\n");	
							
							
							//outputWriter.close();
							
							
							// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
						}
				
						
						
						
							StringTokenizer stoken = new StringTokenizer(
									receivedMessage);
							
							String fargument = null;
							
							
							if(stoken !=null){
								fargument = stoken.nextToken();	
							}
							
							
							
							if (fargument.equals("print2all")) {
								this.sendToAnyone(stoken.nextToken());
						
						
						}
						
					
				} catch (IOException ex) {
					//System.out.println("erro 3");
					//Logger.getLogger(TCPServer.class.getName()).log(
					//		Level.SEVERE, null, ex);
				} catch (NullPointerException e) {
					//System.out.println("SEM LEITURA");
					//System.out.println(e.getMessage());
				} finally {
					
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					outputWriter.close();
					
					
				}

			}
		}

		protected void sendMessage(String message) {
			outputWriter.println(message);
		}

		private void sendToAnyone(String message) {

			for (ConnectionService connection : connections) {
				connection.sendMessage(message);
			}
		}
	}
}

Então preciso reponder alguma coisa tipo "A" assim que alguém se conectar ao socket.

12 Respostas

C

Salve,

Cara para você enviar a string para o cliente é so você escrever pelo objeto outputWriter que você ja criou,
Somente para exemplo eu coloquei no construtor da connectionservice:

public ConnectionService(Socket socket) {
			this.socket = socket;
			
			System.out.println("Dados recebidos "+x);
			try {
				inputReader = new BufferedReader(new InputStreamReader(
				socket.getInputStream()));
				outputWriter = new PrintWriter(socket.getOutputStream(), true);

				outputWriter.println("Bem Vindo!"); // escreve a mensagem para o cliente
				outputWriter.flush();

			} catch (IOException e) {
				System.out.println("erro 2");
			}
		}

Abraço

marciofermino

Amigo nao consegui ou nao sei se isso esta certo.,

um amigo desenvolveu um em VB e esta rodando legal

[quote]Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
On Error Resume Next
If Winsock1.State <> sckClosed Then Winsock1.Close
Winsock1.Accept requestID

lblStatus = "Solicitação de conexão " & requestID & " from " & Winsock1.RemoteHostIP
If Index = 0 Then
sRequestID = requestID
Load Winsock1
Winsock1.LocalPort = 2008
Winsock1.Accept requestID
End If

End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
'On Error Resume Next
Dim strData As String
Winsock1.GetData strData, vbString

' get data from client
Winsock1.GetData sItemData, vbString
lblStatus = "Received: " & vbString & " from " & Winsock1.RemoteHostIP & "(" & sRequestID & ")"
List1.AddItem (strData)
Winsock1.SendData ("LOAD")
Winsock1.SendData ("ON")

End Sub
[code]

Agora no Java não roda nem a pau, e mais notei que quando rodo o socket a navegação da máquina para. é como se eu ficasse sem internet.

Obrigado.

ViniGodoy

Você precisa pedir ao fabricante a documentação do protocolo de comunicação e segui-la à risca.

marciofermino

Entao amigo acho que nao.

Pois em VB que um amigo desenvolveu ficou 100%

so não consegui traduzir para o java.

ViniGodoy

Então seu amigo sabe o protocolo.

Toda comunicação, seja de humanos ou computadores, segue um idioma e uma gramática.

Para os computadores, o protocolo é o manual que dá esse idioma e essa gramática.

Dizer que vc “acha que não” é como achar que alguém foi capaz de falar português sem saber português.

marciofermino

Viny 1 codigo em VB de 2 linhas fez tudo o que precisava fazer

o detalhe que nao uso VB, precisa ser em ajva

java.

O que vem pela porta é uma string

coisa simples,

C

Salve cara,

Cara quando você diz que não roda é por que o cliente não esta recebendo a mensagem?
Eu implementei seu código e fiz um cliente para verificar se a mensagem do servidor é recebida,
Segue o código de exemplo do cliente e servidor.

Servidor:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TCPServer {
	private int serverPort = 2008;
	private ServerSocket serverSocket;
	private List&lt;ConnectionService&gt; connections = new ArrayList&lt;ConnectionService&gt;();

	int x=0;

	public TCPServer() {
		try {
			serverSocket = new ServerSocket(serverPort);
			System.out.println("Waiting...");
			
			while (true) {
				x++;

				Socket socket = serverSocket.accept();
				System.out.println("Connected: " + socket);
				ConnectionService service = new ConnectionService(socket);
				service.start();
			}
		} catch (IOException e) {
			System.out.println("erro 1");
		}

	}

	public static void main(String[] args) {
		new TCPServer();
	}

	class ConnectionService extends Thread {
		private Socket socket;
		private BufferedReader inputReader;
		private PrintWriter outputWriter;

		// private String username;
		public ConnectionService(Socket socket) {
			this.socket = socket;
			
			System.out.println("Dados recebidos "+x);
			try {
				inputReader = new BufferedReader(new InputStreamReader(
				socket.getInputStream()));
				outputWriter = new PrintWriter(socket.getOutputStream(), true);
				outputWriter.println("Bem Vindo!");
				outputWriter.flush();
			} catch (IOException e) {
				System.out.println("erro 2");
			}
		}

		@Override
		public void run() {
			while (true) {
				try {
					String receivedMessage = inputReader.readLine();

					if(receivedMessage!=null){
						System.out.println(receivedMessage+"\n");	
					}
			
					StringTokenizer stoken = new StringTokenizer(receivedMessage);
					String fargument = null;
					if(stoken !=null){
						fargument = stoken.nextToken();	
					}
							
							
							
					if (fargument.equals("print2all")) {
						this.sendToAnyone(stoken.nextToken());
					}
				} catch (IOException ex) {
					//System.out.println("erro 3");
					//Logger.getLogger(TCPServer.class.getName()).log(
					//		Level.SEVERE, null, ex);
				} catch (NullPointerException e) {
					//System.out.println("SEM LEITURA");
					//System.out.println(e.getMessage());
				} finally {
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					outputWriter.close();
				}

			}
		}

		protected void sendMessage(String message) {
			outputWriter.println(message);
		}

		private void sendToAnyone(String message) {
			for (ConnectionService connection : connections) {
				connection.sendMessage(message);
			}
		}
	}
}
Cliente
import java.net.Socket;
import java.net.UnknownHostException;

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;

public class TCPCliente{
	private Socket conexao;
	
	public void conectar(String servidor,int porta){
		try{
			conexao = new Socket(servidor,porta);
			BufferedReader br = new BufferedReader(new InputStreamReader(conexao.getInputStream()));
			String linha = null;
			
			while((linha=br.readLine()) != null)
				System.out.printf("Mensagem do servidor: %s\n",linha);
			br.close();
			conexao.close();
		}catch(UnknownHostException uhe){
			uhe.printStackTrace();
		}catch(IOException ioe){
			ioe.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new TCPCliente().conectar("localhost",2008);
	}
}
marciofermino

Legal
vou tentar explicar;

Tenho dispositivos coletores de dados que ficam na rua..

Esses dispositivos se comunicam atraves de um IP fixo + porta.

Os dispositivos chgegam a se conectar aqui no servidor
chego ate receber mensagens deles.

O que preciso é que
assim que eu receber uma mensagem do cliente (dispostivos), eu preciso responder com o comando "LOAD".

Como disse uma amigo fez isso em VB, poucas linhas e rodando perfeito. Isso sem conhecer protocos, comunicaco etc.

O meu até funciona, só não consegui responder ao cliente.

novamente vou colocar o código em VB, até para mostrar que não exige conhecimento da forma de comunicacao.

Eu só preciso reponder ao cliente assim que ele me enviar 1 primeira mensagem, essa reposta é uma String.

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
On Error Resume Next
If Winsock1.State &lt;&gt; sckClosed Then Winsock1.Close
   Winsock1.Accept requestID
   
  lblStatus = &quot;Solicitação de conexão &quot; & requestID & &quot; from &quot; & Winsock1.RemoteHostIP
  If Index = 0 Then
    sRequestID = requestID
    Load Winsock1
    Winsock1.LocalPort = 2008
    Winsock1.Accept requestID
  End If

End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
'On Error Resume Next
   Dim strData As String
   Winsock1.GetData strData, vbString
        
    ' get data from client
    Winsock1.GetData sItemData, vbString
    lblStatus = &quot;Received: &quot; & vbString & &quot; from &quot; & Winsock1.RemoteHostIP & &quot;(&quot; & sRequestID & &quot;)&quot;
    List1.AddItem (strData)
    [b]Winsock1.SendData (&quot;LOAD&quot;)
    Winsock1.SendData (&quot;ON&quot;)[/b] é isso que preciso
    
End Sub
C

Entendi,

Na sua classe TCPServer você ja exibia uma mensagem assim que o cliente enviava, agora é so enviar uma mensagem para o cliente alem exibila no servidor:

public void run() {
			while (true) {
				try {
					String receivedMessage = inputReader.readLine();

					if(receivedMessage!=null){
						System.out.println(receivedMessage+"\n");	
						outputWriter.println("LOAD"); // Envia a mensagem para o cliente
						outputWriter.flush();
					}
			
					StringTokenizer stoken = new StringTokenizer(receivedMessage);
					String fargument = null;
					if(stoken !=null){
						fargument = stoken.nextToken();	
					}
							
							
							
					if (fargument.equals("print2all")) {
						this.sendToAnyone(stoken.nextToken());
					}
				} catch (IOException ex) {
					//System.out.println("erro 3");
					//Logger.getLogger(TCPServer.class.getName()).log(
					//		Level.SEVERE, null, ex);
				} catch (NullPointerException e) {
					//System.out.println("SEM LEITURA");
					//System.out.println(e.getMessage());
				} finally {
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					// Aqui foi alterado !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
					outputWriter.close();
				}

			}
		}
ViniGodoy

Isso que você escreveu é o protocolo, é a forma de comunicação.
Essa palavra LOAD seguida de ON não é acidental, é?

Como os dados chegam? São na forma de texto? Por que vc usa a classe obsoleta StringTokenizer?

Quando as palavras devem ser respondidas e quais são as palavras disponíveis?

marciofermino

Isso que você escreveu é o protocolo, é a forma de comunicação.
Isso é comando

Essa palavra LOAD seguida de ON não é acidental, é?
[b]Na verdade preciso enviar dois comandos.

  1. Load
  2. ON
    [/b]

Como os dados chegam? São na forma de texto? Por que vc usa a classe obsoleta StringTokenizer?
Sim chegam em forma de textos, pelo menos é o que fabricante afirma. Sobre StringTo peguei no google.

Quando as palavras devem ser respondidas e quais são as palavras disponíveis?[b]Na verdade preciso enviar dois comandos.

  1. Load
  2. ON
    [/b]

Vinim muito obrigado pela ajuda e paciência, agora o que intrigou foi como disse no VB o cara só criou o socket, enviou o comando via data.send e pronto. rodou.

ViniGodoy

Usa o wireshark na linha e compara o que sua aplicação e o que o vb está enviando. As vezes é só a questão do terminador de linha ser \r\n no lugar de só \n.

Não sei o que vc pensa ser um protocolo, mas todos os comandos, e seu formato, fazem parte desse protocolo. Ao dizer que vc tem o comando “LOAD”, que deve ser enviado em texto, no formato ascii, com determinada quebra de linha, vc está descrevendo o que o equipamento espera da comunicação, ou seja, o protocolo (no caso, parte dele por se tratar de uma só mensagem).

Um protocolo não precisa ser complexo. Muitos são até bem simples, como o ftp, que é formado por vários comandinhos em texto.

Criado 29 de abril de 2013
Ultima resposta 2 de mai. de 2013
Respostas 12
Participantes 3