Cliente/Servidor [RESOLVIDO]

Olá gente,
desculpem incomodar, mas não sei se estou fazendo a pergunta no local correto do forum, mas vamos lá: estou tentando desenvolver uma aplicação que contenha um servidor e um cliente. Neste caso eu já fiz várias classes que simulam basicamente um jogo de futsal, e gostaria de tornar o meu cliente um time.
Para isso eu desenvolvi um código bem básico para tentar fazer a comunicação cliente servidor, mas mesmo assim não estou conseguindo fazer com que esse simples exemplo funcione… Eu já pesquisei bastante na net e tento adaptar o código mas mesmo assim não consegui… Desculpem caso o erro for meio bobo…

Segue o código do Cliente:

import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.String;

class Client extends Thread {
	private Socket socket;
	private Scanner dataIn;
	private PrintStream dataOut;
	
	public Client(Socket socket) { 
		this.socket = socket; 
		try{
			this.dataIn = new Scanner(socket.getInputStream());
			this.dataOut = new PrintStream(socket.getOutputStream());
		} catch (java.io.IOException e){}
	}

	public void run() {
	    try {
			dataOut.println("Ola");
			String resposta = dataIn.nextLine();
			System.out.println(resposta);		
            } catch (Exception e){}
		try {
			socket.close(); 
		} catch (Exception e) { System.out.println("A problem was observed while closing the connection");}
	}
	
	public static void main(String args[]) {
		int port = 4893;
		String host = "127.0.0.1";
		try{
			Socket client = new Socket(host, port);	
		} catch(UnknownHostException e){System.out.println("UnknownHostException");}
		catch(IOException e){System.out.println("IOException");}
	}
}

Agora o código do servidor:

import java.io.*;
import java.net.*;
import java.util.*;


public class MyWebServer extends Thread {
	private ServerSocket server;
	private Scanner dataIn;
	private Scanner dataOut;

	public MyWebServer(int port) throws IOException {
		this.server = new ServerSocket(port);
	}

	public void run() {
		Client threadClient;
		try {
		   System.out.println("Waiting...");
		   while (true) {
				Socket socketClient = this.server.accept();
				threadClient = new Client(socketClient);
				threadClient.start();
				
				Scanner dataIn = new Scanner(socketClient.getInputStream());
				PrintStream dataOut = new PrintStream(socketClient.getOutputStream());
				
				
				String entrada = dataIn.nextLine();
				System.out.println(entrada);
				dataOut.println(entrada);
		   }
		} catch (Exception e) {	System.out.println("Problemas...");	}
	}
	
	public static void main(String args[]) {
	int port = 4893;
	try {
		MyWebServer webServer = new MyWebServer(port);
		webServer.start(); 
	} catch (IOException e) { System.out.println("You do not have the necessary access to this computer to create a server."); }

	}
}

Sempre que for postar código, por favor coloque-o entre as tags [ code][/code], Fica muito mais legível.

EDIT: E qual o erro que está ocorrendo? :slight_smile:

O programa está compilando normalmente, a conexão entre o servidor e o cliente aparentemente está funcionando, mas estava testando uma coisa agora usando a seguinte linha de comando:

		while (!dataIn.hasNextLine());

Notei que o programa do servidor para num loop infinito… Ou seja, nunca tem nada no meu canal de comunicação entre o cliente e o servidor… É como se o cliente mandasse uma mensagem que o servidor nunca recebe…

Eu acho que você está confundindo o cliente de verdade, com a representação do cliente no lado do servidor. Veja:

Um Server é iniciado, ele fica esperando conexões.
Um Client abre uma conexão com o Server.
o Server aceita a conexão (server.accept())
o Server cria uma Thread, que irá tratar aquele Cliente, vamos chamar de ClientThread, porém o Client não tem conhecimento de que quem está “conversando” com ele é a ClientThread e não o Server, portanto temos 3 classes rodando aqui.

Segue um exemplo:

Server.java[code]public class Server {

public static void main(String args[]) throws Exception {
	int port = 4893;
	
	ServerSocket server = new ServerSocket(port);
	
	Socket request = null;
	ClientThread client = null;
	
	while(true){
		request = server.accept();
		client = new ClientThread(request);
		client.start();
	}

}

}[/code] ClientThread.java (Thread criada pelo Servidor, para atender ao Client [code]class ClientThread extends Thread {
private Socket socket;

public ClientThread(Socket socket) {
	this.socket = socket;
}

public void run() {
	try {
		DataInputStream dataIn = new DataInputStream(socket.getInputStream());
		String resposta = dataIn.readUTF();
		System.out.println(resposta);
	} catch (Exception e) {
		e.printStackTrace();
	}
	try {
		socket.close();
	} catch (Exception e) {
		System.out
				.println("A problem was observed while closing the connection");
	}
}

}[/code] Client.java (Esse é o cliente de verdade, que envia requisições ao servidor) [code]public class Client {

public static void main(String[] args) throws Exception {
	int port = 4893;
	String host = "127.0.0.1";

	Socket client = new Socket(host, port);
	DataOutputStream writer = new DataOutputStream(client.getOutputStream());
	writer.writeUTF("Oi");
}

}[/code]

:smiley: Funcionou!
Mas agora eu entendi o conceito por trás…
Muito obrigada!

Sem problemas :slight_smile:

Se tiver mais dúvidas pode perguntar, caso não tenha, por favor edite o seu primeiro post do tópico, e adicione a tag [RESOLVIDO] ao Assunto :slight_smile:

Assim quem vê o tópico na lista já sabe que as dúvidas foram sanadas.

digaoneves, estou com um problema parecido … será que pode me ajudar no raciocínio?

Veja bem, tenho uma classe JANELA que faz a interface com o usuário. Nela eu tenho os botões ‘Conectar’, ‘Download’ e ‘Upload’ que chamam os métodos da minha classe CLIENTE.
Tá tudo funcionando direitinho, aparentemente. Porém, após me conectar, se eu clico em ‘Download’ ele executa normal, mas se clico novamente nele ou em outro botão, me retorna um erro: “java.net.SocketException: Socket closed”; Ou seja, só estou conseguindo fazer uma requisição com o CLIENTE para o SERVIDOR.

Veja minhas classes …

CLIENTE …

[code]
package FTPCliente_Servidor;

import java.awt.BorderLayout;
import java.io.;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.
;

public class Cliente {
private Socket conexao;

public Cliente(){}
public Cliente(Socket s)//sobrecarga
{
    this.conexao = s;
}

public void connect(String s) throws IOException {
    try {
        socketCliente = new Socket(s, 4321); 
        System.out.println("Conectado: "+socketCliente.getInetAddress().getHostName());
        out = socketCliente.getOutputStream();
        in = socketCliente.getInputStream();

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

public void upload() {
    try {
        saida = new DataOutputStream(out);
        saida.writeUTF("up");

        File file = new File("source.JPG");
        ObjectOutputStream os = new ObjectOutputStream(out);
        FileInputStream fis = new FileInputStream(file);
        byte[] cache = new byte[4096];

        while (true) {
            int len = fis.read(cache);
            if (len == -1) {
                break;
            }
            os.write(cache, 0, len);
        }
        os.flush();
        os.close();
        //socketCliente.close();
    } catch (Exception e) {
        System.out.println(e);
    }
}

public void download() {

    try {
        saida = new DataOutputStream(out);
        saida.writeUTF("down");

        byte[] cache = new byte[4096];
        ObjectInputStream ois = new ObjectInputStream(in);
        FileOutputStream fos = new FileOutputStream("download//up.JPG");

        while (true) {
            int len = ois.read(cache);
            if (len == -1) {
                break;
            }
            fos.write(cache, 0, len);
        }
        fos.flush();
        fos.close();

    } catch (Exception e) {
        System.out.println(e);
    }
}
       
}

static Socket socketCliente = null;
private OutputStream out;
private InputStream in;
private DataOutputStream saida;

}[/code]

SERVIDOR …


package FTPCliente_Servidor;

import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public final class Servidor extends Thread {

    private Socket conexao;

    public Servidor(Socket s) {
        this.conexao = s;
    }

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

        ServerSocket servidor = (ServerSocket) null;

        try {
            servidor = new ServerSocket(4321, 300);

            while (true) {
                Socket conexao = servidor.accept();
                Thread t = new Servidor(conexao);
                t.start();
            }
        } catch (IOException e) {
        }

    }

    public void run() {
        try {
            InputStream is = conexao.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            String comando = dis.readUTF();

            if (comando.trim().equals("up")) {
                ClienteUpload();
            } else if (comando.trim().equals("down")) {
                ClienteDownload();
            }
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public void ClienteUpload() {
        try {
            InputStream is = conexao.getInputStream();
            byte[] cache = new byte[4096];

            ObjectInputStream ois = new ObjectInputStream(is);

            FileOutputStream fos = new FileOutputStream("upload//up.JPG");
            while (true) {
                int len = ois.read(cache);
                if (len == -1) {
                    break;
                }
                fos.write(cache, 0, len);
            }
            fos.flush();
            fos.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public void ClienteDownload() {
        OutputStream out;
        try {
            out = conexao.getOutputStream();

            File file = new File("source.JPG");
            ObjectOutputStream os = new ObjectOutputStream(out);
            FileInputStream fis = new FileInputStream(file);
            byte[] cache = new byte[4096];

            while (true) {
                int len = fis.read(cache);
                if (len == -1) {
                    break;
                }
                os.write(cache, 0, len);
            }
            os.flush();
            os.close();
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }
}

Gostaria muito de ajuda. Andei pesquisando e parece que devo criar uma Thread no cliente, mas não entendi o motivo … :oops:
Estou aberta a sugestões e reclamações caso meu código não esteja logicamente correto … :oops: