Olá, estou tentando fazer com que duas aplicações rodando na mesma máquina se comuniquem via sockets. Criei duas classes: Server e Client, uma para cada aplicação. A idéia é que tanto o Server quanto o Client executem paralelamente às respectivas aplicações, servindo apenas como uma interface de comunicação, porém estou tendo problemas para fazer isso funcionar (exceções do tipo “java.net.ConnectException: Connection refused: connect”, etc). Se possívvel, gostaria que alguém me ajudasse a entender melhor qual o problema.
Obrigado.
public class Server implements Runnable
{
ServerSocket serverSocket;
public Server(int port) throws Exception{
serverSocket = new ServerSocket(port);
new Thread(this).start();
System.out.println("Server listening to port:" + port);
}
public void run(){
try{
Socket socket = serverSocket.accept();
System.out.println("Client connected!");
BufferedReader message = null;
while(true){
message = new BufferedReader(new InputStreamReader(socket.getInputStream()));
if(message.readLine()=="a"){
//do something
}
else if(message.readLine() == "b"){
//do something else
}
else if(message.readLine() == "close"){
socket.close();
}
else{
System.out.println(message.readLine());
}
}
}catch(Exception e){
e.printStackTrace();
System.out.println("Server: Connection error.");
}
}
}
public class TestClient extends Thread
{
private String server;
private int port;
public TestClient(String server, int porta){
this.server = server;
this.port = porta;
}
public static void main(String[] args){
try{
String server = "localhost";
int port = 1030;
new TestClient(server, port).start();
}catch(Exception e){
System.out.println("Client error.");
e.printStackTrace();
}
}
public void run(){
try{
while(true){
Socket socket = new Socket(server, port);
System.out.println("Conectado a " + server + ":" + port);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject("-message-");
socket.close();
}
}catch(Exception e){
e.printStackTrace();
}
}
}
Cara, por coincidencia tava estudando isso numa apostila da Caelum agorinha.
Eu alterei a porta para “80” e se u programa rodou.
Acredito que tenha alguma configuração de rede sua que esteja barrando o acesso à porta que você configurou.
Abraços,
valeu!
vou testar aqui e já posto o resultado xD!
essa apostila é free? se for, tem como indicar o link ou algo assim?
É free sim amigo.
Pode baixar direto do site da caelum em: http://www.caelum.com.br/download/caelum-java-objetos-fj11.pdf
No final tem um apendice que fala da API de Sockets. Tem um exemplo que acredito que seja o que você procura.
Não sei o que você quer exatamente, mas se quer so comunicar duas apps entre elas nem precisava usar Threads. Dá uma olhada no pdf que você vai entender.
Abraços e boa sorte!
Fala brow,
Temos um artigo do GUJ tambem, se quiser dar uma olhada:
http://guj.com.br/articles/126
Abraco!
Não funcionou só trocando a porta para 80. Na verdade ainda não consegui fazer funcionar totalmente como eu queria. A idéia é utilizar esta comunicação para ligar uma aplicação a um simulador, onde serão modificados valores de sensores, portanto tenho que poder enviar mensagens pelo cliente (aplicação) e receber respostas do servidor (simulador) a qualquer momento. É neste ponto que tenho dificuldades, já que a comunicação funciona e depois parece cair. Caso alguém tenha um exemplo de algo parecido, por favor poste. Obrigado.
Já tentou trocar localhost por 127.0.0.1?
Resolvi o problema. Não precisei trocar o localhost. Não sei como fazer upload de arquivos, então estou postando o código aqui. Talvez seja útil para alguém que queira implementar uma comunicação simples baseada em mensagens. Como tive que fazer isso rápido, talvez (muito provavelmente) não seja a melhor implementação possível, mas está funcionando. Estou postando os códigos tanto do cliente quanto do servidor. Vale lembrar que utilizei essa comunicação para conectar uma aplicação a um simulador de hardware, então o cliente está com o nome de HardwareInterface, pois ele foi usado como uma interface de comunicação com os sensores e atuadores simulados e acessíveis através do servidor. As mensagens e os métodos do cliente também estão definidas em função disso (getValue - para ler sensores; setValue - para passar parâmetros para atuadores; error; e acknowledge message - ack). As mensagens podem ser alteradas dependendo do protocolo que for utilizado.
Servidor:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
class Server {
String GET_VALUE_MSG = "getvalue";
String SET_VALUE_MSG = "setvalue";
String ERR_MSG = "error";
String ACK_MSG = "ack";
int port = 7020;
Socket socket;
String orderMessage = null;
String identifierMessage = null;
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("Aguardando conexao...");
socket = serverSocket.accept();
System.out.println("Conectado com "
+ socket.getRemoteSocketAddress());
listen(socket.getInputStream());
} catch (IOException e) {
System.out.println("Problemas na comunicação: ");
e.printStackTrace();
System.exit(1);
}
}
public void sendToClient(String message) throws IOException {
DataOutputStream output = new DataOutputStream(
socket.getOutputStream());
output.writeInt(message.length());
for (char ch : message.toCharArray())
output.writeChar(ch);
output.flush();
}
private String processMessage(String message){
String returnToClient = "error";
// ...
return returnToClient;
}
private void listen(final InputStream inputStream) {
new Thread(new Runnable() {
DataInputStream dataImputStream = new DataInputStream(inputStream);
public void run() {
try {
while (true) {
int size = dataImputStream.readInt();
int cont = 0;
char[] chars = new char[size];
while (cont < size) {
chars[cont] = dataImputStream.readChar();
cont = cont + 1;
}
String receivedMessage = new String(chars);
String result = ERR_MSG;
try {
result = processMessage(receivedMessage);
} catch (Exception e) {
//handles exception
}
sendToClient(result);
}
} catch (IOException e) {
}
}
}).start();
}
}
Cliente:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class HardwareInterface {
private String GET_VALUE_MSG = "getvalue";
private String SET_VALUE_MSG = "setvalue";
private String ERR_MSG = "error";
private String ACK_MSG = "ack";
private Socket socket;
public HardwareInterface(String host, int port) throws Exception{
try{
socket = new Socket();
socket.connect(new InetSocketAddress(host, port));
}
catch (UnknownHostException e){
System.out.println("Unknown host");
System.out.println("Host: " + host);
System.out.println("Port: " + port);
throw new Exception(e);
}
catch (IOException e){
throw new Exception("Connection to hardware failed.");
}
}
private void sendMessage(String message) throws IOException
{
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
String line = "";
line = message;
output.writeInt(line.length());
for (char ch : line.toCharArray())
output.writeChar(ch);
output.flush();
}
private String waitResponse() throws IOException{
String messageReceived;
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
int size = dataInputStream.readInt();
int cont = 0;
char[] chars = new char[size];
while (cont < size)
{
chars[cont] = dataInputStream.readChar();
cont = cont + 1;
}
messageReceived = new String(chars);
return messageReceived;
}
public int getHardwareValue(String identifier) throws Exception{
int value;
String response;
this.sendMessage(GET_VALUE_MSG);
response = this.waitResponse();
if(response.equals(ACK_MSG)){
this.sendMessage(identifier);
response = this.waitResponse();
value = Integer.parseInt(response);
} else{
throw new Exception("Hardware not found.");
}
return value;
}
public void setHardwareValue(String identifier, int value) throws Exception{
String response;
this.sendMessage(SET_VALUE_MSG);
response=this.waitResponse();
if(response.equals(ACK_MSG)){
this.sendMessage(identifier);
response = this.waitResponse();
if(response.equals(ACK_MSG)){
this.sendMessage(String.valueOf(value));
this.waitResponse();
}
} else{
throw new Exception("Connection to hardware failed.");
}
}
}