[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