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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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... _______________________________________________ mono-bugs maillist - [email protected] http://lists.ximian.com/mailman/listinfo/mono-bugs
