Hola buenas, tengo un servidor en java y un cliente en java y otro cliente en Vb.net. pues bien, la comunicación java->java me vá perfecta, pero entre Vb.net -> java hace cosas raras y al final no funciona.
Sé bastante poco de sockets, todo son pedazos de programas de un sitio y de otro que he ido sacando, si alguien es un iluminado y me saca de la duda, le querré mucho:
Servidor Java
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Servidor extends JFrame {
private JTextField campoIntroducir;
private JTextArea areaPantalla;
private ObjectOutputStream salida;
private ObjectInputStream entrada;
private ServerSocket servidor;
private Socket conexion;
private int contador = 1;
// configurar GUI
public Servidor()
{
super( "Servidor" );
Container contenedor = getContentPane();
// crear campoIntroducir y registrar componente de escucha
campoIntroducir = new JTextField();
campoIntroducir.setEditable( false );
campoIntroducir.addActionListener(
new ActionListener() {
// enviar mensaje al cliente
public void actionPerformed( ActionEvent evento )
{
enviarDatos( evento.getActionCommand() );
campoIntroducir.setText( "" );
}
}
);
contenedor.add( campoIntroducir, BorderLayout.NORTH );
// crear areaPantalla
areaPantalla = new JTextArea();
contenedor.add( new JScrollPane( areaPantalla ),
BorderLayout.CENTER );
setSize( 300, 150 );
setVisible( true );
} // fin del constructor de Servidor
// configurar y ejecutar el servidor
public void ejecutarServidor()
{
// configurar servidor para que reciba conexiones; procesar las conexiones
try {
// Paso 1: crear un objeto ServerSocket.
servidor = new ServerSocket( 12345, 100 );
while ( true ) {
try {
esperarConexion(); // Paso 2: esperar una conexión.
obtenerFlujos(); // Paso 3: obtener flujos de entrada y salida.
procesarConexion(); // Paso 4: procesar la conexión.
}
// procesar excepción EOFException cuando el cliente cierre la conexión
catch ( EOFException excepcionEOF ) {
System.err.println( "El servidor terminó la conexión" );
}
finally {
cerrarConexion(); // Paso 5: cerrar la conexión.
++contador;
}
} // fin de instrucción while
} // fin del bloque try
// procesar problemas con E/S
catch ( IOException excepcionES ) {
excepcionES.printStackTrace();
}
} // fin del método ejecutarServidor
// esperar que la conexión llegue, después mostrar información de la conexión
private void esperarConexion() throws IOException
{
mostrarMensaje( "Esperando una conexión\n" );
conexion = servidor.accept(); // permitir al servidor aceptar la conexión
mostrarMensaje( "Conexión " + contador + " recibida de: " +
conexion.getInetAddress().getHostName() );
}
// obtener flujos para enviar y recibir datos
private void obtenerFlujos() throws IOException
{
// establecer flujo de salida para los objetos
salida = new ObjectOutputStream( conexion.getOutputStream() );
salida.flush(); // vaciar búfer de salida para enviar información de encabezado
// establecer flujo de entrada para los objetos
entrada = new ObjectInputStream( conexion.getInputStream() );
mostrarMensaje( "\nSe recibieron los flujos de E/S\n" );
}
// procesar la conexión con el cliente
private void procesarConexion() throws IOException
{
// enviar mensaje de conexión exitosa al cliente
String mensaje = "Conexión exitosa";
enviarDatos( mensaje );
// habilitar campoIntroducir para que el usuario del servidor pueda enviar mensajes
establecerCampoTextoEditable( true );
do { // procesar los mensajes enviados por el cliente
// leer el mensaje y mostrarlo en pantalla
try {
mensaje = ( String ) entrada.readObject();
mostrarMensaje( "\n" + mensaje );
}
// atrapar problemas que pueden ocurrir al tratar de leer del cliente
catch ( ClassNotFoundException excepcionClaseNoEncontrada ) {
mostrarMensaje( "\nSe recibió un tipo de objeto desconocido" );
}
} while ( !mensaje.equals( "CLIENTE>>> TERMINAR" ) );
} // fin del método procesarConexion
// cerrar flujos y socket
private void cerrarConexion()
{
mostrarMensaje( "\nFinalizando la conexión\n" );
establecerCampoTextoEditable( false ); // deshabilitar campoIntroducir
try {
salida.close();
entrada.close();
conexion.close();
}
catch( IOException excepcionES ) {
excepcionES.printStackTrace();
}
}
// enviar mensaje al cliente
private void enviarDatos( String mensaje )
{
// enviar objeto al cliente
try {
salida.writeObject( "SERVIDOR>>> " + mensaje );
salida.flush();
mostrarMensaje( "\nSERVIDOR>>> " + mensaje );
}
// procesar problemas que pueden ocurrir al enviar el objeto
catch ( IOException excepcionES ) {
areaPantalla.append( "\nError al escribir objeto" );
}
}
// método utilitario que es llamado desde otros subprocesos para manipular a
// areaPantalla en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
// mostrar mensaje del subproceso de ejecución despachador de eventos
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // actualiza areaPantalla
{
areaPantalla.append( mensajeAMostrar );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
// método utilitario que es llamado desde otros subprocesos para manipular a
// campoIntroducir en el subproceso despachador de eventos
private void establecerCampoTextoEditable( final boolean editable )
{
// mostrar mensaje del subproceso de ejecución despachador de eventos
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // establece la capacidad de modificar a campoIntroducir
{
campoIntroducir.setEditable( editable );
}
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
public static void main( String args[] )
{
Servidor aplicacion = new Servidor();
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
aplicacion.ejecutarServidor();
}
} // fin de la clase Servidor
Cliente Java
// Cliente que lee y muestra la información que le envía un Servidor.
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Cliente extends JFrame {
private JTextField campoIntroducir;
private JTextArea areaPantalla;
private ObjectOutputStream salida;
private ObjectInputStream entrada;
private String mensaje = "";
private String servidorChat;
private Socket cliente;
// inicializar servidorChat y configurar GUI
public Cliente( String host )
{
super( "Cliente" );
servidorChat = host; // establecer el servidor al que se va a conectar este cliente
Container contenedor = getContentPane();
// crear campoIntroducir y registrar componente de escucha
campoIntroducir = new JTextField();
campoIntroducir.setEditable( false );
campoIntroducir.addActionListener(
new ActionListener() {
// enviar mensaje al servidor
public void actionPerformed( ActionEvent evento )
{
enviarDatos( evento.getActionCommand() );
campoIntroducir.setText( "" );
}
}
);
contenedor.add( campoIntroducir, BorderLayout.NORTH );
// crear areaPantalla
areaPantalla = new JTextArea();
contenedor.add( new JScrollPane( areaPantalla ),
BorderLayout.CENTER );
setSize( 300, 150 );
setVisible( true );
} // fin del constructor de Cliente
// conectarse al servidor y procesar mensajes del servidor
private void ejecutarCliente()
{
// conectarse al servidor, obtener flujos, procesar la conexión
try {
conectarAServidor(); // Paso 1: crear un socket para realizar la conexión
obtenerFlujos(); // Paso 2: obtener los flujos de entrada y salida
procesarConexion(); // Paso 3: procesar la conexión
}
// el servidor cerró la conexión
catch ( EOFException excepcionEOF ) {
System.err.println( "El cliente termino la conexión" );
}
// procesar los problemas que pueden ocurrir al comunicarse con el servidor
catch ( IOException excepcionES ) {
excepcionES.printStackTrace();
}
finally {
cerrarConexion(); // Paso 4: cerrar la conexión
}
} // fin del método ejecutarCliente
// conectarse al servidor
private void conectarAServidor() throws IOException
{
mostrarMensaje( "Intentando realizar conexión\n" );
// crear Socket para realizar la conexión con el servidor
cliente = new Socket( InetAddress.getByName( servidorChat ), 12345 );
// mostrar la información de la conexión
mostrarMensaje( "Conectado a: " +
cliente.getInetAddress().getHostName() );
}
// obtener flujos para enviar y recibir datos
private void obtenerFlujos() throws IOException
{
// establecer flujo de salida para los objetos
salida = new ObjectOutputStream( cliente.getOutputStream() );
salida.flush(); // vacíar búfer de salida para enviar información de encabezado
// establecer flujo de entrada para los objetos
entrada = new ObjectInputStream( cliente.getInputStream() );
mostrarMensaje( "\nSe recibieron los flujos de E/S\n" );
}
// procesar la conexión con el servidor
private void procesarConexion() throws IOException
{
// habilitar campoIntroducir para que el usuario del cliente pueda enviar mensajes
establecerCampoTextoEditable( true );
do { // procesar mensajes enviados del servidor
// leer mensaje y mostrarlo en pantalla
try {
mensaje = ( String ) entrada.readObject();
mostrarMensaje( "\n" + mensaje );
}
// atrapar los problemas que pueden ocurrir al leer del servidor
catch ( ClassNotFoundException excepcionClaseNoEncontrada ) {
mostrarMensaje( "\nSe recibió un objeto de tipo desconocido" );
}
} while ( !mensaje.equals( "SERVIDOR>>> TERMINAR" ) );
} // fin del método procesarConexion
// cerrar flujos y socket
private void cerrarConexion()
{
mostrarMensaje( "\nCerrando conexión" );
establecerCampoTextoEditable( false ); // deshabilitar campoIntroducir
try {
salida.close();
entrada.close();
cliente.close();
}
catch( IOException excepcionES ) {
excepcionES.printStackTrace();
}
}
// enviar mensaje al servidor
private void enviarDatos( String mensaje )
{
// enviar objeto al servidor
try {
salida.writeObject( "CLIENTE>>> " + mensaje );
salida.flush();
mostrarMensaje( "\nCLIENTE>>> " + mensaje );
}
// procesar los problemas que pueden ocurrir al enviar el objeto
catch ( IOException excepcionES ) {
areaPantalla.append( "\nError al escribir el objeto" );
}
}
// método utilitario que es llamado desde otros subprocesos para manipular a
// areaPantalla en el subproceso despachador de eventos
private void mostrarMensaje( final String mensajeAMostrar )
{
// mostrar mensaje del subproceso de ejecución de la GUI
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // actualiza areaPantalla
{
areaPantalla.append( mensajeAMostrar );
areaPantalla.setCaretPosition(
areaPantalla.getText().length() );
}
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
// método utilitario que es llamado desde otros subprocesos para manipular a
// campoIntroducir en el subproceso despachador de eventos
private void establecerCampoTextoEditable( final boolean editable )
{
// mostrar mensaje del subproceso de ejecución de la GUI
SwingUtilities.invokeLater(
new Runnable() { // clase interna para asegurar que la GUI se actualice apropiadamente
public void run() // establece la capacidad de modificar campoIntroducir
{
campoIntroducir.setEditable( editable );
}
} // fin de la clase interna
); // fin de la llamada a SwingUtilities.invokeLater
}
public static void main( String args[] )
{
Cliente aplicacion;
if ( args.length == 0 )
aplicacion = new Cliente( "127.0.0.1" );
else
aplicacion = new Cliente( args[ 0 ] );
aplicacion.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
aplicacion.ejecutarCliente();
}
} // fin de la clase Cliente
Cliente VB.net
Código del form
Imports WindowsApplication1.Cliente
Public Class Form1
Inherits System.Windows.Forms.Form
Dim WithEvents WinSockCliente As New Cliente
Private Sub btnConectar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConectar.Click
With WinSockCliente
'Determino a donde se quiere conectar el usuario
.IPDelHost = txtIP.Text
.PuertoDelHost = txtPuerto.Text
'Me conecto
.Conectar()
'Deshabilito la posibilidad de conexion
WinSockCliente.EnviarDatos(txtMensaje.Text + vbCrLf)
txtIP.Enabled = False
txtPuerto.Enabled = False
btnConectar.Enabled = False
'Habilito la posibilidad de enviar mensajes
btnEnviarMensaje.Enabled = True
txtMensaje.Enabled = True
End With
End Sub
Private Sub WinSockCliente_DatosRecibidos(ByVal datos As String) Handles WinSockCliente.DatosRecibidos
MsgBox("El servidor envio el siguiente mensaje: " & datos)
End Sub
Private Sub WinSockCliente_ConexionTerminada() Handles WinSockCliente.ConexionTerminada
MsgBox("Finalizo la conexion")
'Habilito la posibilidad de una reconexion
txtIP.Enabled = True
txtPuerto.Enabled = True
btnConectar.Enabled = True
'Deshabilito la posibilidad de enviar mensajes
btnEnviarMensaje.Enabled = False
txtMensaje.Enabled = False
End Sub
Private Sub btnEnviarMensaje_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnviarMensaje.Click
'Envio lo que esta escrito en la caja de texto del mensaje
WinSockCliente.EnviarDatos(txtMensaje.Text)
End Sub
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
End
End Sub
End Class
Libreria
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.IO
Public Class Cliente
#Region "VARIABLES"
Private Stm As Stream 'Utilizado para enviar datos al Servidor y recibir datos del mismo
Private m_IPDelHost As String 'Direccion del objeto de la clase Servidor
Private m_PuertoDelHost As String 'Puerto donde escucha el objeto de la clase Servidor
#End Region
#Region "EVENTOS"
Public Event ConexionTerminada()
Public Event DatosRecibidos(ByVal datos As String)
#End Region
#Region "PROPIEDADES"
Public Property IPDelHost() As String
Get
IPDelHost = m_IPDelHost
End Get
Set(ByVal Value As String)
m_IPDelHost = Value
End Set
End Property
Public Property PuertoDelHost() As String
Get
PuertoDelHost = m_PuertoDelHost
End Get
Set(ByVal Value As String)
m_PuertoDelHost = Value
End Set
End Property
#End Region
#Region "METODOS"
Public Sub Conectar()
Dim tcpClnt As TcpClient
Dim tcpThd As Thread 'Se encarga de escuchar mensajes enviados por el Servidor
tcpClnt = New TcpClient()
'Me conecto al objeto de la clase Servidor,
' determinado por las propiedades IPDelHost y PuertoDelHost
tcpClnt.Connect(IPDelHost, PuertoDelHost)
Stm = tcpClnt.GetStream()
'Creo e inicio un thread para que escuche los mensajes enviados por el Servidor
tcpThd = New Thread(AddressOf LeerSocket)
tcpThd.Start()
End Sub
Public Sub EnviarDatos(ByVal Datos As String)
Dim BufferDeEscritura() As Byte
BufferDeEscritura = Encoding.ASCII.GetBytes(Datos)
If Not (Stm Is Nothing) Then
'Envio los datos al Servidor
Stm.Write(BufferDeEscritura, 0, BufferDeEscritura.Length)
End If
End Sub
#End Region
#Region "FUNCIONES PRIVADAS"
Private Sub LeerSocket()
Dim BufferDeLectura() As Byte
While True
Try
BufferDeLectura = New Byte(100) {}
'Me quedo esperando a que llegue algun mensaje
Stm.Read(BufferDeLectura, 0, BufferDeLectura.Length)
'Genero el evento DatosRecibidos, ya que se han recibido datos desde el Servidor
RaiseEvent DatosRecibidos(Encoding.ASCII.GetString(BufferDeLectura))
Catch e As Exception
Exit While
End Try
End While
'Finalizo la conexion, por lo tanto genero el evento correspondiente
RaiseEvent ConexionTerminada()
End Sub
#End Region
End Class