2011-01-06 14 views
9

Estoy tratando de hacer una aplicación Java de forma cliente/servidor. El cliente es una GUI en SWT que muestra datos del servidor. El servidor está conectado a una base de datos.make a client server aplicación java

Bien, disculpe por eso, es una pregunta clásica, estoy seguro, pero no sé cómo comenzar.

En un proyecto en el que trabajé implementaron mucha magia con Proxy.newProxyInstance() para invocar el servidor de Glassfish de forma transparente.

No quiero usar un servidor de Glassfish. Solo quiero algo simple en Java simple. Pero el concepto de proxies parece bastante bueno.

¿Tiene ideas o ejemplos de tal cosa? ¿Cómo escribo la parte del servidor para manejar las solicitudes de los clientes?

Gracias de antemano

Fluminis

+0

Iba a sugerir probar el enfoque JMS Producer/Consumer, pero quiere algo sencillo. –

Respuesta

34

Voy a explicar TCP:
El concepto básico es que debe ejecutar un "Servidor" en una máquina. Ese servidor acepta clientes que esperan una conexión. Cada conexión pasa por un puerto (ya sabes, espero ...).
Siempre use los puertos por encima de 1024 debido a los puertos inferiores a 1025 son la mayor parte del tiempo reservado para protocolos estándar (como HTTP (80), FTP (21), Telnet, ...)

Sin embargo, la creación de un servidor en Java se hace de esta manera:

ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on. 

"Socket" es la palabra que probablemente esté buscando si quiere investigar.
Y para conectar su cliente a un servidor que tiene que escribir esto:

Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port 

Pero ahora, no existe todavía una conexión.El servidor tiene que aceptar al cliente en espera (como noté aquí arriba):

Socket connectionToTheClient = server.accept(); 

¡Hecho! ¡Tu conexión está establecida! La comunicación es como File-IO. Lo único que debe tener en cuenta es que debe decidir cuándo quiere vaciar el búfer y realmente enviar los datos a través del zócalo.
El uso de un PrintStream para el texto-escritura es muy práctico:

OutputStream out = yourSocketHere.getOutputStream(); 
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true 
ps.println("Hello, Other side of the connection!"); 
// Now, you don't have to flush it, because of the auto-flush flag we turned on. 

Un BufferedReader para el texto, la lectura es la buena (mejor *) Opción:

InputStream in = yourSocketHere.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
String line = br.readLine(); 
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection. 

Esperamos que usted puede comenzar con la creación de redes con esta ¡información!
PD: Por supuesto, todo el código de red debe ser try-catched para IOExceptions.

EDIT: Olvidé escribir por qué no siempre es la mejor opción. Un BufferedReader utiliza un búfer y lee todo lo que puede en el búfer. Pero a veces no quiere que el BufferedReader robe los bytes después de la nueva línea y los coloque en su propio búfer.
ejemplo corto:

InputStream in = socket.getInputStream(); 
BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
// The other side says hello: 
String text = br.readLine(); 
// For whatever reason, you want to read one single byte from the stream, 
// That single byte, just after the newline: 
byte b = (byte) in.read(); 

Pero el BufferedReader ya tiene ese byte, que desea leer, en su memoria intermedia. Entonces, al llamar al in.read() se devolverá el siguiente byte en el último byte en el búfer del lector.

Por lo tanto, en esta situación, la mejor solución es usar DataInputStream y administrarlo a su manera para saber cuánto tiempo va a ser la cadena y leer solo ese número de bytes y convertirlos en una cadena. O: Se utiliza

DataInputStream.readLine()

Este método no utiliza un búfer y lee byte a byte y comprueba si hay una nueva línea. Entonces este método no roba los bytes del InputStream subyacente.


EDIT: Usted puede desarrollar su propio protocolo en el que se puede solicitar una llamada al método utilizando Java reflexión. Por ejemplo:

String className = ...; 
String methodName = ...; 
Class[] methodParamTypes = ...; 
Object[] methodParams = ...; 
Class cl = Class.forName(className); 
Method me = cl.getDelcaredMethod(methodName, methodParamTypes); 
Object returnValue = me.invoke(this, methodParams); 

vez que tenga su objeto lo puede enviar al otro lado de la conexión con la serialización: ObjectOuputStreams y ObjectInputStreams. Con estas dos clases, puede escribir y leer objetos a través de una secuencia.

Object obj = ...; // Your object you want to write through the stream. (Needs to implement java.io.Serializable) 
ObjectOutputStream oos = new ObjectOuptputStream(socket.getOutputStream()); 
oos.writeObject(oos); 
oos.reset(); // (***) 
// Don't close it! Otherwise the connection will be closed as well. 

Y en el otro lado de la conexión:

ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
Object object = ois.readObject(); // Read the object 
// Don't close it! 
// Then cast it to whatever you want. 

(***): Salida my question para más información sobre reset() y cuándo usarlo.

+0

Gracias por su respuesta. Entiendo bien con usted, ejemplo, cómo recuperar texto. ¿Pero es posible con soket invocar un método en el servidor y obtener un objeto complejo a cambio? – fluminis

+0

Eche un vistazo a ObjectOutputStream y ObjectInputStream. –

+1

también, puede que esté pensando en Java RMI (invocación de método remoto): hay buena documentación sobre él. –

3

Si desea escribir un programa simple de tipo cliente-servidor, puede seguir los consejos dados en este tutorial.

Si quieres hacer algo un poco más complicado, en Java simple como dices, entonces tal vez necesites mirar RMI.

Sin embargo, en estos días, web services son furor y es posible que a la larga sea más simple.

1
  1. Identificar los servicios que desea proporcionar (loadThing, editThing, makeThingBelch)
  2. decidir sobre protocolo de comunicación/mensajería (http parece straightfoward.)
  3. implementar los servicios, las pruebas unitarias con frecuencia para asegurarse de que funcionan .
  4. AHORA comience a escribir el cliente, teniendo en cuenta que podría tener que agregar nuevos servicios o cambiar los ya existentes.

Una cosa que viene a la mente es ¿por qué quieres escribirlo en 'simple java' en lugar de usar un servidor de aplicaciones existente? algo de EJB3 para abstraer y administrar la comunicación, la seguridad, la integridad transaccional, etc.

5

Glassfish puede tener más potencia de fuego de la que necesita, pero no me rendiría al aprovechar una biblioteca existente.

Algunas opciones para tomas:

Si decide ir más hacia los servicios web que los sockets, Jetty es el camino a seguir para HTTP de pequeña huella.