Main Site Documentation

Change from UDP to TCP several times


#1

Hi, i’m trying to change from UDP to TCP several times by configurating the socket parameters.

First i have this line:

 Socket Servidor = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

i use it to send a broadcast message to find all the available devices on the network.
then, i change to TCP with this code:

Servidor = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

and send some data to the remote ip, but when i try to change to UDP again, i recieve an exception: “No free sockets” :o


#2

are you explicitly closing the sockets?


#3

It’s easy to be socket short with WIZNET chips… First you have natively only 4 sockets. Then, it’s usualy advised to configure the stack WIZnet_W5100.Enable() with the 4th parameter as “true” which reserves one socket for internal use… So don’t forget to close cleanly any socket once you’re done with them ! :wink:

If you want more advices, please paste here a longer piece of your code :think: !


#4

well i’m using the close method after sending the TCP message, and then when i send the UDP broadcast message, my ethernet device doesn’t answer.

after that, i change to TCP and send a message and my device receives it good.

but when i try to change to UDP again i get the “No free sockets” exception. :frowning:


#5

Please paste your full code here !


#6

OK, this is my full code:

using System;
using System.IO;
using System.Text;
using Microsoft.SPOT;
using System.Threading;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.Net;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Net.Sockets;
using GHIElectronics.NETMF.Net.NetworkInformation;
using Socket = GHIElectronics.NETMF.Net.Sockets.Socket;
namespace EthernetFez
{
    public class Program
    {
        #region Variables estaticas
        static byte[] ip = { 192, 168, 1, 144 };   
        static byte[] mac = { 0x28, 0x08, 0xDC, 0x15, 0xFF, 0x00 };    
        static byte[] subnet = { 255, 255, 255, 0 }; 
        static byte[] gateway = { 192, 168, 1, 1 };    
        static Thread LecturaPuerto = new Thread(LecturaUDP);
        static UInt16 seleccion = 0;
        static Socket Servidor;
        static IPEndPoint remoteEndPoint;
        static EndPoint entradaremota;
        static UInt16 Ipremota = new int();
        static byte[] Salida = new byte[10];
        static UInt16 NumPuerto = 0;
        static Estructura_Modulos[] Modulos = new Estructura_Modulos[5];
        #endregion
        struct Estructura_Modulos
        {
            public int ModulosRed;
            public string Respuesta;
            public byte[] DireccionMac;
            public byte[] DireccionIP;
            public byte[] MascaraSubRed;
            public byte[] PuertaEnlace;
        }
        public static void Main()
        {
            InterruptPort BotonEntrada =
                new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.LDR, true,
                Port.ResistorMode.PullUp,
                Port.InterruptMode.InterruptEdgeHigh);
            BotonEntrada.OnInterrupt += new NativeEventHandler(BotonEntrada_Interrption);
            WIZnet_W5100.Enable(SPI.SPI_module.SPI1, (Cpu.Pin)FEZ_Pin.Digital.Di10, (Cpu.Pin)FEZ_Pin.Digital.Di9, true);
            entradaremota = new IPEndPoint(IPAddress.Any, 100);
            NetworkInterface.EnableStaticIP(ip, subnet, gateway, mac);
            #region Carga datos de modulo local en la estructura
            Modulos[0].Respuesta = "Unknown";
            Modulos[0].DireccionMac = mac;
            Modulos[0].DireccionIP = ip;
            Modulos[0].MascaraSubRed = subnet;
            Modulos[0].PuertaEnlace = gateway;
            #endregion
            Thread.Sleep(Timeout.Infinite);
        }
        public static void BotonEntrada_Interrption(uint puerto, uint estado, DateTime hora)
        {
            if (seleccion == 0)
            {
                Servidor = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                Ipremota = 0;
                #region Valores extraidos de la estructura
                string txtcomando = "";
                Debug.Print("Datos del modulo:     " + Ipremota.ToString());
                Debug.Print("Respuesta del modulo: " + Modulos[Ipremota].Respuesta);
                txtcomando = "";
                for (UInt16 i = 0; i < Modulos[Ipremota].DireccionMac.Length; i++)
                    txtcomando += Byte_ToHex(Modulos[Ipremota].DireccionMac[i]) + ":";
                txtcomando = txtcomando.Substring(0, txtcomando.Length - 1);
                Debug.Print("Direccion Mac:        " + txtcomando);
                txtcomando = Byte_ToText(Modulos[Ipremota].DireccionIP, '.');
                Debug.Print("Direccion IP:         " + txtcomando);
                txtcomando = Byte_ToText(Modulos[Ipremota].MascaraSubRed, '.');
                Debug.Print("Mascara de subred:    " + txtcomando);
                txtcomando = Byte_ToText(Modulos[Ipremota].PuertaEnlace, '.');
                Debug.Print("Puerta de enlace:     " + txtcomando);
                #endregion
                NumPuerto = 7100;
                remoteEndPoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), NumPuerto);
                Salida = Encoding.UTF8.GetBytes("WIZ220FIND");
                Servidor.SendTo(Salida, remoteEndPoint);
                string txtoutput = "";
                for (UInt16 i = 0; i < Salida.Length; i++)
                    txtoutput += Convert.ToChar(Salida[i]).ToString();
                Debug.Print("           Comando " + txtoutput + " enviado al puerto " + remoteEndPoint.Port.ToString());
                NumPuerto = 1460;
                remoteEndPoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), NumPuerto);
                Salida = Encoding.UTF8.GetBytes("FIND");
                Servidor.SendTo(Salida, remoteEndPoint);
                txtoutput = "";
                for (UInt16 i = 0; i < Salida.Length; i++)
                    txtoutput += Convert.ToChar(Salida[i]).ToString();
                Debug.Print("           Comando " + txtoutput + " enviado al puerto " + remoteEndPoint.Port.ToString());
                Debug.Print(" ");
                if (!LecturaPuerto.IsAlive)
                    LecturaPuerto.Start();
            }
            if (seleccion == 1)
            {
                ConexionTCPIP(Byte_ToText(Modulos[1].DireccionIP, '.'), 23);
                Servidor.Send(Encoding.UTF8.GetBytes("Hello world!!!\r\n"));
                Servidor.Close();
                Debug.Print("Dato enviado y conexion cerrada");
            }
            if (seleccion >= 1)
                seleccion = 0;
            else
                seleccion += 1;
        }
        public static void ConexionTCPIP(string TxtIP, int Puerto)
        {
            Debug.Print("Se ha seleccionado el puerto " + Puerto.ToString() + " para conectarse a la IP " + TxtIP);
            Servidor = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            remoteEndPoint = new IPEndPoint(IPAddress.Parse(TxtIP), Puerto);
            Servidor.Connect(remoteEndPoint);
        }
        public static void LecturaUDP()
        {
            while (true)
            {
                if (Servidor.Poll(-1, SelectMode.SelectRead))
                {
                    Debug.Print("Leyendo modulo..."); Debug.Print(" ");
                    Ipremota++;
                    byte[] entrada = new byte[Servidor.Available];
                    int cuenta = Servidor.ReceiveFrom(entrada, ref entradaremota);
                    string txtcomando = "";
                    for (UInt16 i = 0; i <= 9; i++)
                        txtcomando += Convert.ToChar(entrada[i]).ToString();
                    if (txtcomando == "WIZ220find")
                        MakeEstructuraWIZ220(entrada);
                    else
                        MakeEstructuraFIND(entrada);
                    Modulos[0].ModulosRed = Ipremota;
                    Debug.Print(" "); Debug.Print(" ");
                }
            }
        }
        static void MakeEstructuraFIND(byte[] paquete)
        {
            string txtcomando = "";
            byte[] direccionmac = new byte[6];
            byte[] direccionip = new byte[4];
            byte[] mascarasubred = new byte[4];
            byte[] puertaenlace = new byte[4];
            for (UInt16 i = 0; i <= 3; i++)
                txtcomando += Convert.ToChar(paquete[i]).ToString();
            Modulos[Ipremota].Respuesta = txtcomando;
            for (UInt16 i = 4; i < 9; i++)
                direccionmac[i - 4] = paquete[i];
            Modulos[Ipremota].DireccionMac = direccionmac;
            for (UInt16 i = 11; i <= 14; i++)
                direccionip[i - 11] = paquete[i];
            Modulos[Ipremota].DireccionIP = direccionip;
            for (UInt16 i = 15; i <= 18; i++)
                mascarasubred[i - 15] = paquete[i];
            Modulos[Ipremota].MascaraSubRed = mascarasubred;
            for (UInt16 i = 19; i <= 22; i++)
                puertaenlace[i - 19] = paquete[i];
            Modulos[Ipremota].PuertaEnlace = puertaenlace;
            #region Valores extraidos de la estructura
            Debug.Print("Datos del modulo:     " + Ipremota.ToString());
            Debug.Print("Respuesta del modulo: " + Modulos[Ipremota].Respuesta);
            txtcomando = "";
            for (UInt16 i = 0; i < Modulos[Ipremota].DireccionMac.Length; i++)
                txtcomando += Byte_ToHex(Modulos[Ipremota].DireccionMac[i]) + ":";
            txtcomando = txtcomando.Substring(0, txtcomando.Length - 1);
            Debug.Print("Direccion Mac:        " + txtcomando);
            txtcomando = Byte_ToText(Modulos[Ipremota].DireccionIP, '.');
            Debug.Print("Direccion IP:         " + txtcomando);
            txtcomando = Byte_ToText(Modulos[Ipremota].MascaraSubRed, '.');
            Debug.Print("Mascara de subred:    " + txtcomando);
            txtcomando = Byte_ToText(Modulos[Ipremota].PuertaEnlace, '.');
            Debug.Print("Puerta de enlace:     " + txtcomando);
            #endregion
        }
        static void MakeEstructuraWIZ220(byte[] paquete)
        {
            string txtcomando = "";
            byte[] direccionmac = new byte[6];
            byte[] direccionip = new byte[4];
            byte[] mascarasubred = new byte[4];
            byte[] puertaenlace = new byte[4];
            for (UInt16 i = 0; i <= 9; i++)
                txtcomando += Convert.ToChar(paquete[i]).ToString();
            Modulos[Ipremota].Respuesta = txtcomando;
            for (UInt16 i = 10; i < 15; i++)
                direccionmac[i - 10] = paquete[i]; 
            Modulos[Ipremota].DireccionMac = direccionmac;
            for (UInt16 i = 16; i <= 19; i++)       
                direccionip[i - 16] = paquete[i];       
            Modulos[Ipremota].DireccionIP = direccionip;
            for (UInt16 i = 20; i <= 23; i++)        
                mascarasubred[i - 20] = paquete[i];       
            Modulos[Ipremota].MascaraSubRed = mascarasubred;
            for (UInt16 i = 24; i <= 27; i++)      
                puertaenlace[i - 24] = paquete[i];          
            Modulos[Ipremota].PuertaEnlace = puertaenlace;
            #region Valores extraidos de la estructura
            Debug.Print("Datos del modulo:     " + Ipremota.ToString());
            Debug.Print("Respuesta del modulo: " + Modulos[Ipremota].Respuesta);
            txtcomando = "";
            for (UInt16 i = 0; i < Modulos[Ipremota].DireccionMac.Length; i++)
                txtcomando += Byte_ToHex(Modulos[Ipremota].DireccionMac[i]) + ":";
            txtcomando = txtcomando.Substring(0, txtcomando.Length - 1);
            Debug.Print("Direccion Mac:        " + txtcomando);
            txtcomando = Byte_ToText(Modulos[Ipremota].DireccionIP, '.');
            Debug.Print("Direccion IP:         " + txtcomando);
            txtcomando = Byte_ToText(Modulos[Ipremota].MascaraSubRed, '.');
            Debug.Print("Mascara de subred:    " + txtcomando);
            txtcomando = Byte_ToText(Modulos[Ipremota].PuertaEnlace, '.');
            Debug.Print("Puerta de enlace:     " + txtcomando);
            #endregion
        }
        static string Byte_ToHex(int number)
        {
            string hex = "0123456789ABCDEF";
            if (number > 256)
                return new string(new char[] { hex[(number & 0xF000) >> 12], hex[(number & 0xF00) >> 8], hex[(number & 0xF0) >> 4], hex[number & 0x0F] });
            else
                return new string(new char[] { hex[(number & 0xF0) >> 4], hex[number & 0x0F] });
        }
        static string Byte_ToText(byte[] Dir, char Separador)
        {
            string Txt = "";
            string txt = "";
            try
            {
                for (UInt16 i = 0; i < Dir.Length; i++)
                    Txt += Dir[i].ToString() + Separador.ToString();
                txt = Txt.Substring(0, Txt.Length - 1);
            }
            catch (Exception ex) { Debug.Print("Error en: " + ex.ToString()); }
            return txt;
        }
    }
}

#7

I don’t see when you are closing the Servidor UDP socket. You need to close it before assigning a TCP socket into the same variable, if you wish, but this is not clean. It’s not related with closing an UDP session, as you know the UDP sessions are connectionless.

You should have to separate sockets names : one for UDP you can keep open all the time if you need so, and a different one you use for TCP and close it when you don’t need anymore ! ::slight_smile:


#8

ok i just tried that, and works fine for me. i have now one socket for TCP and the other one for UDP.

i just close the tcp connection to change to a new one. thank you. ;D