[Mono-bugs] [Bug 77618][Nor] Changed - TcpListener does not attend
the port
bugzilla-daemon at bugzilla.ximian.com
bugzilla-daemon at bugzilla.ximian.com
Thu Feb 23 10:35:13 EST 2006
Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.
Changed by esanchezfo at gmail.com.
http://bugzilla.ximian.com/show_bug.cgi?id=77618
--- shadow/77618 2006-02-23 06:36:29.000000000 -0500
+++ shadow/77618.tmp.32275 2006-02-23 10:35:13.000000000 -0500
@@ -115,6 +115,883 @@
publicar aquí un pequeño ejemplo e intrucciones precisas de como
reproducir el problema?
Muchas gracias
Jordi,
+
+------- Additional Comments From esanchezfo at gmail.com 2006-02-23 10:35 -------
+Thanks a lot:
+
+
+Here the mega basic server in C#, after the same in C++ and the client
+is a Lipman Terminal model Nurit 8100, 8200, and 8000 using GPRS.
+
+First two utily classes:
+
+- ByteByNibble, work a byte as two nibbles
+- Tools, has basic presentation functions
+- MainClass, contains the basic server
+
+
+Class ByteByNibble:
+
+#region Librerias
+
+using System;
+using System.Collections;
+
+#endregion
+
+
+namespace BasicServer
+{
+ /// <summary>
+ /// Representa la mitad de un byte
+ /// </summary>
+ public sealed class ByteByNibble
+ {
+ #region Constantes
+
+ /// <summary>
+ /// 8 bits por cada byte
+ /// </summary>
+ public const int BYTE_BIT_LENGTH = 8;
+
+ /// <summary>
+ /// 2 nibbles por cada byte
+ /// </summary>
+ public const int BYTE_NIBBLE_LENGTH = 2;
+
+ #endregion
+
+
+ #region Miembros
+
+ private BitArray _LeftPart;
+
+ private BitArray _RigthPart;
+
+ #endregion
+
+
+ #region Propiedades
+
+ public int Digit
+ {
+ get
+ {
+ return int.Parse (this.IntLeftPart.ToString () +
+this.IntRigthPart.ToString ());
+ }
+ }
+
+
+ public string DigitString
+ {
+ get
+ {
+ string result;
+
+ int left;
+ int rigth;
+
+
+ left = this.IntLeftPart;
+ rigth = this.IntRigthPart;
+
+ result = string.Empty;
+
+ if (left < 10)
+ {
+ result += "0";
+ }
+
+ result += left;
+
+ if (rigth < 10)
+ {
+ result += "0";
+ }
+
+ result += rigth;
+
+ return result;
+ }
+ }
+
+
+ public string DigitAsHexaString
+ {
+ get
+ {
+ return
+ Tools.DecimalToHexa (this.IntLeftPart) +
+ Tools.DecimalToHexa (this.IntRigthPart);
+ }
+ }
+
+
+ public byte Value
+ {
+ set
+ {
+ BitArray temp;
+
+
+ temp = new BitArray (new byte [] {value});
+
+ this._LeftPart = new BitArray (BYTE_BIT_LENGTH / 2);
+ this._RigthPart = new BitArray (BYTE_BIT_LENGTH / 2);
+
+ this._LeftPart.Set (0, temp.Get (4));
+ this._LeftPart.Set (1, temp.Get (5));
+ this._LeftPart.Set (2, temp.Get (6));
+ this._LeftPart.Set (3, temp.Get (7));
+
+ this._RigthPart.Set (0, temp.Get (0));
+ this._RigthPart.Set (1, temp.Get (1));
+ this._RigthPart.Set (2, temp.Get (2));
+ this._RigthPart.Set (3, temp.Get (3));
+ }
+ get
+ {
+ BitArray result;
+
+
+ result = new BitArray (BYTE_BIT_LENGTH);
+
+ result.Set (0, this._RigthPart.Get (0));
+ result.Set (1, this._RigthPart.Get (1));
+ result.Set (2, this._RigthPart.Get (2));
+ result.Set (3, this._RigthPart.Get (3));
+
+ result.Set (4, this._LeftPart.Get (0));
+ result.Set (5, this._LeftPart.Get (1));
+ result.Set (6, this._LeftPart.Get (2));
+ result.Set (7, this._LeftPart.Get (3));
+
+ return BitArrayToByte (result);
+ }
+ }
+
+
+ public BitArray LeftPart
+ {
+ get
+ {
+ return this._LeftPart;
+ }
+ }
+
+
+ public BitArray RigthPart
+ {
+ get
+ {
+ return this._RigthPart;
+ }
+ }
+
+
+ public int IntLeftPart
+ {
+ set
+ {
+ this._LeftPart = new BitArray (new byte [] {(byte) value});
+ this._LeftPart.Length = 4;
+ }
+ get
+ {
+ return BitArrayToInt (this._LeftPart);
+ }
+ }
+
+
+ public int IntRigthPart
+ {
+ set
+ {
+ this._RigthPart = new BitArray (new byte [] {(byte) value});
+ this._RigthPart.Length = 4;
+ }
+ get
+ {
+ return BitArrayToInt (this._RigthPart);
+ }
+ }
+
+ #endregion
+
+
+ #region Constructor
+
+ public ByteByNibble ()
+ {
+ this._LeftPart = new BitArray (BYTE_BIT_LENGTH / 2);
+ this._RigthPart = new BitArray (BYTE_BIT_LENGTH / 2);
+ }
+
+
+ /// <summary>
+ /// Parte el valor en nibbles, por ejemplo 52 es 5 y 2
+ /// </summary>
+ /// <param name="value">Valor entero que se soporta para representar
+desde 0 hasta 99</param>
+ public ByteByNibble (int value)
+ {
+ if (value > 99)
+ {
+ throw new ArgumentOutOfRangeException ("value", "Solo se
+representan valores entre 0 y 99 con dos nibbles");
+ }
+
+ if (value < 10)
+ {
+ this.IntLeftPart = 0;
+ this.IntRigthPart = value;
+ return;
+ }
+
+ this.IntLeftPart = int.Parse (value.ToString () [0].ToString ());
+ this.IntRigthPart = int.Parse (value.ToString () [1].ToString ());
+ }
+
+
+ public ByteByNibble (int left, int rigth)
+ {
+ this.IntLeftPart = left;
+ this.IntRigthPart = rigth;
+ }
+
+
+ public ByteByNibble (byte value)
+ {
+ this.Value = value;
+ }
+
+ #endregion
+
+
+ #region Funciones
+
+
+ #endregion
+
+
+ #region Funciones compartidas
+
+ public static byte BitArrayToByte (BitArray values)
+ {
+ return BitArrayToByteArray (values) [0];
+ }
+
+
+ public static byte [] BitArrayToByteArray (BitArray values)
+ {
+ byte [] result;
+
+
+ result = new byte [(int) Math.Ceiling ((double) values.Length /
+ByteByNibble.BYTE_BIT_LENGTH)];
+
+ values.CopyTo (result, 0);
+
+ return result;
+ }
+
+
+ public static int BitArrayToInt (BitArray values)
+ {
+ return Convert.ToInt32 (BitArrayToByte (values));
+ }
+
+
+ public static byte GetByteFromNibbleDigits (int leftValue, int
+rightValue)
+ {
+ return GetByteFromNibbleDigits ((byte) leftValue, (byte) rightValue);
+ }
+
+
+ public static byte GetByteFromNibbleDigits (byte leftValue, byte
+rightValue)
+ {
+ BitArray left;
+ BitArray right;
+
+ // TODO: No es completamente correcto el paso de entero a byte
+ // mejorar la forma en la se genera el byte
+ left = new BitArray (new byte [] {leftValue});
+
+ right = new BitArray (new byte [] {rightValue});
+
+ right.Set (4, left [0]);
+ right.Set (5, left [1]);
+ right.Set (6, left [2]);
+ right.Set (7, left [3]);
+
+ return (byte) BitArrayToInt (right);
+ }
+
+
+
+
+ public static int GetLeftNibbleValue (byte value)
+ {
+ BitArray left;
+
+ bool [] tmp;
+
+
+ left = new BitArray (value);
+
+ tmp = new bool [4];
+
+ tmp [0] = left [0];
+ tmp [1] = left [1];
+ tmp [2] = left [2];
+ tmp [3] = left [3];
+
+ left = new BitArray (tmp);
+
+ return Convert.ToInt32 (left);
+ }
+
+
+ public static int GetRightNibbleValue (byte value)
+ {
+ BitArray right;
+
+ bool [] tmp;
+
+
+ right = new BitArray (value);
+
+ tmp = new bool [4];
+
+ tmp [0] = right [4];
+ tmp [1] = right [5];
+ tmp [2] = right [6];
+ tmp [3] = right [7];
+
+ right = new BitArray (tmp);
+
+ return Convert.ToInt32 (right);
+ }
+
+
+ #endregion
+ }
+}
+
+
+Class Tools:
+
+
+#region Librerias
+
+using System;
+using System.Collections;
+using System.Text;
+
+#endregion
+
+
+namespace BasicServer
+{
+ /// <summary>
+ /// Funciones de uso general
+ /// </summary>
+ public sealed class Tools
+ {
+ #region Constantes
+
+ /// <summary>
+ /// Define el valor comodin para el uso de valores hexadecimales en
+el relleno a la derecha para un total impar de cifras
+ /// </summary>
+ private const int F = 15;
+
+ private const int DECIMAL_MAXBIT = 32;
+
+ private const int BASE10 = 10;
+
+ private static char [] cHexa = new char [] {'A', 'B', 'C', 'D', 'E',
+'F'};
+
+ private static int [] iHexaNumeric = new int [] {10, 11, 12, 13, 14,
+15};
+
+ private static int [] iHexaIndexes = new int [] {0, 1, 2, 3, 4, 5};
+
+ private const int ASCIIDIFFERENCE = 48;
+
+ #endregion
+
+
+ #region Enumeraciones
+
+ public enum TheHexaValues
+ {
+ A = 10,
+ B = 11,
+ C = 12,
+ D = 13,
+ E = 14,
+ F = 15
+ }
+
+ #endregion
+
+
+ #region Herramientas para presentacion de campos
+
+ public static string ByteArrayToStringNibbles (byte [] values, int
+renglonByteCount)
+ {
+ StringBuilder result;
+
+ int nibbleMark;
+ int renglonMark;
+
+
+ result = new StringBuilder ();
+
+ nibbleMark = ByteByNibble.BYTE_BIT_LENGTH /
+ByteByNibble.BYTE_NIBBLE_LENGTH;
+ renglonMark = renglonByteCount * ByteByNibble.BYTE_NIBBLE_LENGTH;
+
+ foreach (byte value in values)
+ {
+ result.Append (new ByteByNibble (value).DigitAsHexaString);
+ nibbleMark -= ByteByNibble.BYTE_NIBBLE_LENGTH +
+ByteByNibble.BYTE_NIBBLE_LENGTH;
+
+ if (nibbleMark == 0)
+ {
+ result.Append (" ");
+ nibbleMark = ByteByNibble.BYTE_BIT_LENGTH /
+ByteByNibble.BYTE_NIBBLE_LENGTH;
+
+ renglonMark --;
+
+ if (renglonMark == 0)
+ {
+ result.Append ("\n");
+
+ renglonMark = renglonByteCount * ByteByNibble.BYTE_NIBBLE_LENGTH;
+ }
+ }
+ }
+
+ return result.ToString ();
+ }
+
+ #endregion
+
+
+ #region Conversiones generales
+
+ public static int [] StringToIntArray (string values)
+ {
+ int [] result;
+ int i;
+
+
+ result = new int [values.Length];
+
+ for (i = 0; i < values.Length; i++)
+ {
+ result [i] = int.Parse (values [i].ToString ());
+ }
+
+ return result;
+ }
+
+
+ public static int [] DoubleToIntArray (double value)
+ {
+ string [] temp;
+
+ int i;
+ int [] result;
+
+
+ temp = value.ToString ().Split
+(System.Globalization.CultureInfo.CurrentCulture.NumberFormat.CurrencyDecimalSeparator
+[0]);
+
+ result = new int [temp [0].Length + 2];
+
+ for (i = 0; i < temp [0].Length; i++)
+ {
+ result [i] = int.Parse (temp [0][i].ToString ());
+ }
+
+ if (temp.Length == 2)
+ {
+ result [i++] = int.Parse (temp [1][0].ToString ());
+
+ if (temp [1].Length > 1)
+ {
+ result [i] = int.Parse (temp [1][1].ToString ());
+ }
+ }
+
+ return result;
+ }
+
+
+ #endregion
+
+
+ #region Conversiones de tipos y bases
+
+ public static int HexaToDecimal (string hexaValue)
+ {
+ return BaseToDecimal (hexaValue, 16);
+ }
+
+
+ public static string DecimalToHexa (int decimalValue)
+ {
+ return DecimalToBase (decimalValue, 16);
+ }
+
+
+ public static string DecimalToBase (int decimalValue, int numericBase)
+ {
+ string strBin;
+
+ int [] result;
+
+ int maxBit;
+
+ int rem;
+
+
+ maxBit = DECIMAL_MAXBIT;
+
+ strBin = string.Empty;
+
+ result = new int [DECIMAL_MAXBIT];
+
+ for(; decimalValue > 0; decimalValue /= numericBase)
+ {
+ rem = decimalValue % numericBase;
+ result [--maxBit] = rem;
+ }
+
+ foreach (int resultValue in result)
+ {
+ if (resultValue >= BASE10)
+ {
+ strBin += cHexa [resultValue % BASE10];
+ }
+ else
+ {
+ strBin += resultValue;
+ }
+ }
+
+ strBin = strBin.TrimStart (new char [] {'0'});
+
+ if (strBin.Length == 0)
+ {
+ strBin = "0";
+ }
+
+ return strBin;
+ }
+
+
+ public static int BaseToDecimal (string sBase, int numericBase)
+ {
+ int dec = 0;
+
+ int b;
+
+ int iProduct=1;
+
+ string sHexa = "";
+
+ int i;
+
+ string sValue;
+
+
+ if (numericBase > BASE10)
+ {
+ for (i = 0;i < cHexa.Length; i++)
+ {
+ sHexa += cHexa.GetValue(i).ToString ();
+ }
+ }
+
+ for (i = sBase.Length - 1; i >= 0; i--, iProduct *= numericBase)
+ {
+ sValue = sBase [i].ToString ();
+
+ if (sValue.IndexOfAny (cHexa) >= 0)
+ {
+ b = iHexaNumeric [sHexa.IndexOf (sBase [i])];
+ }
+ else
+ {
+ b = (int) sBase[i] - ASCIIDIFFERENCE;
+ }
+
+ dec += (b * iProduct);
+ }
+
+ return dec;
+ }
+
+
+ public static int GetIntFromHexaAsChar (char hexaLetterValue)
+ {
+ switch (hexaLetterValue)
+ {
+ case '0': return 0;
+ case '1': return 1;
+ case '2': return 2;
+ case '3': return 3;
+ case '4': return 4;
+ case '5': return 5;
+ case '6': return 6;
+ case '7': return 7;
+ case '8': return 8;
+ case '9': return 9;
+ default: return (int) (TheHexaValues) Enum.Parse (typeof
+(TheHexaValues), hexaLetterValue.ToString());
+ }
+ }
+
+
+ #endregion
+
+
+ #region Extracion de partes de arreglos
+
+ public static byte [] ExtractPartFromByteArray (byte [] values, int
+startIndex, int length)
+ {
+ if (length == 0)
+ {
+ return null;
+ }
+
+ byte [] result;
+
+
+ result = new byte [length];
+
+ Array.Copy (values, startIndex, result, 0, length);
+
+ return result;
+ }
+
+
+ #endregion
+ }
+}
+
+
+And Class MainClass, with the server (of course the test of this code
+consider the no use of threads):
+
+
+using System;
+using System.Net;
+using System.Net.Sockets;
+using System.Threading;
+using System.Text;
+
+
+namespace BasicServer
+{
+ /// <summary>
+ /// Descripción breve de Class1.
+ /// </summary>
+ class MainClass
+ {
+ /// <summary>
+ /// Punto de entrada principal de la aplicación.
+ /// </summary>
+ [STAThread]
+ static void Main (string[] args)
+ {
+ // El primer argumento sera el puerto en el que funcione el servicio
+
+
+
+ TcpListener listener;
+ TcpClient client;
+ NetworkStream clientStream;
+
+ byte [] values;
+
+ int serverPort;
+
+ int readByteCount;
+
+
+ if (args.Length > 0)
+ {
+ serverPort = int.Parse (args [0]);
+ }
+ else
+ {
+ serverPort = 5975;
+ }
+
+ Console.WriteLine ("Iniciando servidor, en {0}...", serverPort);
+
+ listener = new TcpListener (System.Net.IPAddress.Any, serverPort);
+ listener.Start ();
+ // The listener use the default values, but i try modifing the
+ReceiveTimeOut and the SendTimeOut in many ways
+
+ while (true)
+ {
+ client = listener.AcceptTcpClient ();
+
+ Console.WriteLine ("Cliente conectado");
+
+ values = new byte [client.ReceiveBufferSize];
+
+ clientStream = client.GetStream ();
+
+ // I send in the test values from 0 to 150 or 300 bytes, this
+small server only
+ // receive 30 bytes and show them in order to confirm the
+correctness of the service in order to
+ // allow receive something from someone.
+ readByteCount = clientStream.Read (values, 0,
+client.ReceiveBufferSize);
+
+ Console.WriteLine ("Recibi {0} bytes", readByteCount);
+
+ values = Tools.ExtractPartFromByteArray (values, 0, readByteCount);
+
+ Console.WriteLine (Tools.ByteArrayToStringNibbles (values, 16));
+
+ // Send anything to check the response in the Nurit Terminal
+ values = new byte [] {0, 0, 0, 0};
+ clientStream.Write (values, 0, values.Length);
+
+ Console.WriteLine ("Cerrando conexión");
+ client.Close ();
+ }
+
+ //listener.Stop ();
+ }
+ }
+}
+
+
+Ready, this three classes compose the basic server, one maked to
+listen and show, no more (but the listen with GPRS works only 50% of
+the times)
+
+Now the ultraBasic server in C++:
+
+
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+
+void main(int a,char *b[]);
+
+void main(int a,char *b[])
+{ int archivo_socket,nuevo_socket;
+ int puerto;
+ size_t namelen;
+
+ int leer;
+ unsigned char buffer[1025];
+
+ int conexiones,i;
+
+ /* Familia de protocolos a usar, en este caso de INTERNET */
+ struct sockaddr_in sin={AF_INET};
+
+ /* Ignora es status de los procesos hijos, esto asegura que mueren
+cuando
+ cuando el padre muere */
+ signal(SIGCHLD,SIG_IGN);
+
+ if(a==1)
+ puerto=1976;
+ else
+ puerto=atoi(b[1]);
+
+ /* Familia, tipo de comunicacion, protocolo */
+ archivo_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
+ if(archivo_socket<0)
+ { perror("No puedo abrir el SOCKET debido a");
+ exit(1);
+ }
+
+ /* Puerto */
+ sin.sin_port=htons(puerto);
+
+ /* Enlazo la arquitectura de red con el puerto */
+ if(bind(archivo_socket,(struct sockaddr *)&sin,sizeof(sin))<0)
+ { perror("Bind fallo");
+ exit(1);
+ }
+
+ /* Escuchar */
+ if(listen(archivo_socket,5)<0)
+ { perror("Listen fallo");
+ exit(1);
+ }
+ namelen=sizeof(sin);
+
+ conexiones=0;
+ while(1)
+ { /* Nueva conexion establecida */
+ nuevo_socket=accept(archivo_socket,(struct sockaddr
+*)&sin,&namelen);
+ printf("%d\n",nuevo_socket);
+ if(nuevo_socket<0)
+ { perror("Accept fallo");
+ exit(1);
+ }
+ conexiones++;
+ printf("Conexion establecida - %d !!!\n",conexiones);
+ if(fork()==0)
+ { close(archivo_socket);
+ while(1)
+ { leer=read(nuevo_socket,buffer,1024);
+ if(leer<=0)
+ { printf("Conexion cerrada!!!\n");
+ close(nuevo_socket);
+ exit(0);
+ }
+ for(i=0;i<leer;i++)
+ { if(i%16==0)
+ printf("\n");
+ printf("%02x ",buffer[i]);
+ }
+ printf("\n");
+ }
+ }
+ close(nuevo_socket);
+ }
+}
+
+
+The clients GPRS fails work TCP/IP open port error the 50% of the
+times, but the DIAL and Ethernet works fine... unfortunadelly the main
+use if over GPRS and the project must be ready at February 24 is to
+sat tomorrow I'll die or survive the presentation in private
+conference and the next week in public.
+
+Thanks a lot. For your help. I guess the problem may be the listener
+but not in the code, behind the AcceptTcpClient...
More information about the mono-bugs
mailing list