none
Cliente - Servidor con sockets

    Pregunta

  • Hola gente! Llevo un par de dias tratando de realizar una conexion entre el cliente y el servidor para mandar una simple cadena (luego ya se desarrollaria mas). Estoy usando Visual C# 2008 Express. El caso es que he conseguido en internet bastantes codigos pero no he conseguido que ninguno me funcione correctamente. Seriais tan amables de dejarme alguno si teneis algun codigo por ahí??

    Muchas gracias con antelacion!!!
    martes, 25 de agosto de 2009 8:00

Respuestas

Todas las respuestas

  • ESTE ES EL CODIGO MAS CERCANO A LO QUE QUIERO QUE HE CONSEGUIDO:

    Servidor:
    try
                {
                    IPAddress ipa = Dns.GetHostEntry("localhost").AddressList[0];
                    IPEndPoint ipe = new IPEndPoint(ipa, int.Parse(txtPuerto.Text));
                    //O en una sola línea así...
                    //IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.0.1"), int.Parse(txtPuerto.Text));
                    Socket socket = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
                    socket.Bind(ipe);
                    socket.Listen(100);
                    txtRespuesta.Text = "Esperando a un cliente...";
                    Application.DoEvents();
                    sockresp = socket.Accept();
                    txtRespuesta.AppendText("\n");
                    txtRespuesta.Text += "\r\nConectado...\r\n";
                    Application.DoEvents();
                    int bytesRecibidos = 0;
                    string datosRecibidos = "";
                    byte[] buffer = new byte[1024];
                    do
                    {
                        bytesRecibidos = sockresp.Receive(buffer,
                        buffer.Length, 0);
                        datosRecibidos +=
                        System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, buffer.Length);
                        txtRespuesta.Text += "\r\n" + datosRecibidos;
                        Application.DoEvents();
                    } while (bytesRecibidos > 0);
                    string estado = "OK";
                    byte[] respuesta = new byte[1024];
                    respuesta = Encoding.ASCII.GetBytes(estado);
                    sockresp.Send(respuesta);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
    Cliente:

    try
                {
    
                    IPAddress ipdestino = IPAddress.Parse(txtIPDestino.Text);
                    //Dns.Resolve("localhost").AddressList[0];
                    IPEndPoint ipe = new IPEndPoint(ipdestino, int.Parse(txtPuerto.Text));
    
                    //CREO EL SOCKET
                    Socket socket_cliente = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    //CONECTO EL SOCKET
                    socket_cliente.Connect(ipe);
                    int bytes = 0;
                    string respuesta = "";
    
                    //CODIFICO EL PAQUETE A MANDAR
                    byte[] datosEnvio = System.Text.ASCIIEncoding.ASCII.GetBytes(txtEnvio.Text);
                    //CREO UN ARRAY PARA GUARDAR EL PAQUETE RECIBIDO
                    byte[] datosRecibidos = new byte[1024];
                    //ENVIO LOS DATOS
                    socket_cliente.Send(datosEnvio, datosEnvio.Length, SocketFlags.None);
                    //VOY COGIENDO LA RESPUESTA Y LA MUESTRO
                    do
                    {
                        bytes = socket_cliente.Receive(datosRecibidos,
                        datosRecibidos.Length, 0);
                        respuesta =
                        System.Text.ASCIIEncoding.ASCII.GetString(datosRecibidos);
                    } while (bytes > 0);
                    txtRespuesta.Text += "\r\n" + respuesta;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

    Alguien sabe porque se me quedan congelados tanto el cliente como el servidor??

    En el momento que fuerzo cerrar al cliente, en el servidor si que me llega la cadena que me interesa mandar!!


    Espero que alguien sepa como lo puedo solucionar!

    Un saludo y muchas gracias de nuevo.
    martes, 25 de agosto de 2009 8:25
  • hola,

    no se si has podido ver estos links

    Socket Programming in C# .Net: File Transfer using C# Socket
    Socket Programming in C# .Net: Client Socket for Beginner
    CodeProject: TCP/IP Chat Application Using C#

    como veras todos traen ejemplos que podras descargar y estudiar

    aunque te recomiendo le des una mirada a todo el namespace que provee .net

    System.Net.Sockets

    y especialemnte a dos clases

    TcpClient
    TcpListener

    alli mismo en los link encontraras ejemplos, pero creo quee stas clases son mas simples de usar que la del socket directamente

    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    martes, 25 de agosto de 2009 12:43
  • Si eso ya lo he mirado todo y el tema de sockets lo manejo mas o menos pero el problema es que se me queda colgado!!! He echo algun cambio en el programa para repartir 2 funciones de enviar y recibir pero el problema es a la hora del bucle porque si no hago bucle y mando solo 1 paquete funciona correctamente pero no quiero estar abriendo y cerrando el socket cada vez que quiera mandar algo.

    No se si me he explicado!!!


    El codigo del cliente se me quedaria asi:


    private void button1_Click(object sender, EventArgs e)
            {
                        byte[] data = new byte[1024]; //Cramos un byte[> para recibir el mensaje 
                      //de bienvenida del servidor 
                      int sent; //una variable que nos dice cuanto hemos enviado 
                      IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(txtIPAddress.Text), int.Parse(txtPort.Text)); 
                      //Creamos un IPEndPoint con el ip del servidor y puerto del servidor 
                      //al que deseamos conectarnos, en este caso lo uso local 
    
                      //Creamos el socket igual al del servidor 
                      Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 
    
                      try 
                      { 
                            server.Connect(ipep);//Intentamos conectar el socket 
                      } 
                      catch (SocketException)
                      { 
                            //Si hay excepcion imprimimos error y salimos del programa con return 
                            Console.WriteLine("No se pudo conectar con el servidor {0}", ipep.Address); 
                            return; 
                      }
    
                      while (true)
                      {
                          string message = txtData.Text;
                            try 
                            {//Enviamos el mensaje. 
                                  sent = SendData(server, Encoding.ASCII.GetBytes(message)); 
                            } 
                            catch (SocketException) 
                            {//Si hay excepcion nos salimos pq no hay conexion 
                                  Console.WriteLine("No se ha encontrado conexion con el servidor {0}", ipep.Address); 
                                  return; 
                            }//Si se ejeucta el comando exit nos salimos 
                            if (message == "exit" ) 
                                  break; 
                      }
                      //Indicamos que nos desocnectamos y cerramos el socket 
                      server.Shutdown(SocketShutdown.Both); 
                      server.Close(); 
            }
    Y el codigo del servidor se me quedaria asi:


    private void botonEstado_Click(object sender, EventArgs e)
                {
                    byte[] data = new byte[1024]; //creamos un byte[> para enviar la bienvenida 
                      IPEndPoint ipep = new IPEndPoint(Dns.GetHostEntry("localhost").AddressList[0],int.Parse(txtPuerto.Text));
                      //Con el IpAdress.Any esuchamos en cualquier interfaz de red.. y el 9050 
                      //es el puerto en el que escuharemos 
    
                      //creamos un socket de tipo internwtwork, stream y tcp 
                      Socket newsock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); 
                      try 
                      { 
                            newsock.Bind(ipep); //lo bindeamos para que se ancle al puerto especificaco 
                      } 
                      catch (SocketException) 
                      { 
                            //si aqui hay error es que ese puerto esta en uso y entonces es probable 
                            //que otra instancia de este programa ya este corriendo 
                            Console.WriteLine("Al parecer otra instancia del servidor ya esta corriendo" ); 
                            return; //si es asi damos un return para salirnos de la funcion y terminar 
                            //el programa 
                      } 
    
                      newsock.Listen(1); //escuchamos con el socket en el puerto especifaco 
    
                      Socket client = newsock.Accept(); //Esto acepta la conexion cuando recibe 
                      //una peticion... esto se queda esperando hasta que ocurra 
                      IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint; //creamos un IPEndPoint 
    
                      for (int m = 0; m < 2; m++) 
                      {//Este for nos sirve para leer infinitamente los mensajes que nos llegan 
                            try 
                            { 
                                  data = ReceiveData(client); //Llama a recibir mensajes del socket cliente 
                                  //esto se queda esperando hasta recibir un mensaje
                                  string message = Encoding.ASCII.GetString(data); //si recibimos un 
                                  //mensaje entonces lo decoficamos a un string 
                                  if (message == "exit" ) //si recibimos exit nos salimos.. 
                                        break; 
                                  labelestado.Text = message; //si no entonces lo imprimimos 
                                  m--; //restamos al for para que sea infinito... 
                            } 
                            catch (SocketException)
                            { 
                                  Console.WriteLine("No se encontro conexion con el cliente {0}", newclient.Address); 
                                  return; 
                                  //si enocntramos un error es que se perido la conexion y con el return nos 
                                  //salimos de la funcion 
                            } 
                      } 
                      //cerramos el socket del cliente 
                      client.Shutdown(SocketShutdown.Both); 
                      client.Close(); 
                      //Ceramos el socket con el que escuchamos 
                      newsock.Shutdown(SocketShutdown.Both); 
                      newsock.Close(); 
                }
    No se porque puede ser!!! Si me podrían ayudar!!!


    Muchas gracias de nuevo!

    martes, 25 de agosto de 2009 13:43
  • Si estas en Windows Vista o Windows 7 o Server 2008 o Server 2008 R2

    debes ejecutar ese programa con provilegios de administrador, sino el sistema no permitirá que se abran los puertos.



    Colabora con la comunidad, si éste mensaje te ha sido de utilidad, márcalo como respuesta correcta.
    Juan Carlos Ruiz Pacheco
    Ingeniero de Sistemas
    Microsoft MVP C#
    MCP,MCTS,DCE+Platino,OCA,OCP
    Visita Mi Blog C# XNA Sistemas Operativos
    miércoles, 26 de agosto de 2009 20:20