Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
String, AnsiString, Ascii y la madre de Embarcadero

Buenas a todos.

No se si os habrá pasado a vosotros, pero a mi me tiene frito y no encuentro solución (de momento), además, creo que la culpa es de mis padres (R.I.P.) y de la madre que pario a los de Embarcadero.

El caso es que mi nombre es César, si, con acento en la letra E y lógicamente lo uso como tal (se que algún forero es muy crítico con los acentos)

¿Que me pasa? que si mando una cadena con mi nombre a ... digamos un socket no se envia "César" sino "CÚsar', ¿Comorrrr? Investigo, investigo, mucho, pero mucho. Y la conclusión a la que he llegado es la siguiente:

Que necesito enviar la siguiente secuencia ASCII (67, 130, 115, 97, 114) osea "César" y que me pasa ... que sale (67, 233, 115, 97, 114) osea "CÙsar".

Da igual como defina la cadena, ShortString, AnsiString, String, UnicodeString, WideString, array of char, array of byte, array of word, siempre que miro el carácter me devuelve 233 en vez de 130.

¿Se os ocurre como solucionarlo?

Gracias por adelantado.
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #2  
Antiguo 20-09-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cesarsoftware,

Cita:
Empezado por cesarsoftware
...si mando una cadena con mi nombre a...digamos un socket no se envia "César" sino "CÚsar'...(67, 130, 115, 97, 114) osea "César"...sale (67,233, 115, 97, 114) osea "CÙsar"...
Te comento: El ordinal 130 corresponde al carácter "," y el ordinal 233 corresponde al carácter "é".

Revisa este código:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
const
   A1 : Array[1..5] of Byte = (67,233,115,97,114);
   A2 : Array[1..5] of Byte = (67,218,115,97,114);

var
   i : Integer;
   AuxStr : String;
   Secuencia : String;

begin

   // 1- Secuencia 'César' en Representación Ordinal

   Secuencia := EmptyStr;
   AuxStr := 'César';

   for i := 1 to Length(AuxStr) do
      Secuencia := Secuencia + IntToStr(Ord(AuxStr[i])) + ',';

   ShowMessage(Secuencia + ' = ' + '67,233,115,97,114,');

   // 2- Arreglo (67,233,115,97,114) en Representación de Carácteres

   Secuencia := EmptyStr;

   for i := Low(A1) to High(A1) do
      Secuencia := Secuencia + Chr(A1[i]);

   ShowMessage(Secuencia + ' = ' + 'César');

   // 3- Secuencia 'CÚsar' en Representación Ordinal

   Secuencia := EmptyStr;
   AuxStr := 'CÚsar';

   for i := 1 to Length(AuxStr) do
      Secuencia := Secuencia + IntToStr(Ord(AuxStr[i])) + ',';

   ShowMessage(Secuencia + ' = ' + '67,218,115,97,114,');

   // 4- Arreglo (67,218,115,97,114) en Representación de Carácteres

   Secuencia := EmptyStr;

   for i := Low(A2) to High(A2) do
      Secuencia := Secuencia + Chr(A2[i]);

   ShowMessage(Secuencia + ' = ' + 'CÚsar');

end;
El código anterior en Delphi 7 sobre Windows 7 Professional x32, representa la secuencia (C, é, s, a, r) en valores ordinales (67, 233, 115, 97, 114) y la secuencia (C,Ù,s,a,r) en valores ordinales (67, 218, 115, 97, 114) según lo esperado, Pregunto: ¿Las secuencias de carácteres del código anterior se representan correctamente en sus valores ordinales en tu sistema?.

Revisa este link:
Cita:
ASCII Code - The extended ASCII table : http://www.ascii-code.com/
Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 20-09-2013 a las 23:03:38.
Responder Con Cita
  #3  
Antiguo 23-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Gracias Nelson por contestar, luego comprobaré el código que planteas, pero creo que por lo que dices en nuestra máquina/windows es asi, pero no en el resto.

Es decir, cuando un telnet remoto conecta con mi aplicación, recibe ese ascii 233 en vez del 130 que el espera, no se mi explico bien, en la tabla ascii standar (la de toda la vida) para la E acentuada el carácter es 130 no 233, ¿Como puedo hacer que use la tabla "normal"

Como por ejemplo esta tabla http://www.elcodigoascii.com.ar/

__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #4  
Antiguo 23-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Cita:
Empezado por nlsgarcia Ver Mensaje
Pregunto: ¿Las secuencias de carácteres del código anterior se representan correctamente en sus valores ordinales en tu sistema?.

Revisa este link:

Espero sea útil

Nelson.
Si según la tabla que tu muestras si, pero debe haber variaas tablas.
"There are several different variations of the 8-bit ASCII table. The table below is according to ISO 8859-1, also called ISO Latin-1. Codes 129-159 contain the Microsoft® Windows Latin-1 extended characters."

¿Como sabemos que tabla usar?
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #5  
Antiguo 23-09-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cesarsoftware,

Cita:
Empezado por cesarsoftware
...por lo que dices en nuestra máquina/windows es así, pero no en el resto...

...según la tabla que tu muestras si, pero debe haber varias tablas...¿Como sabemos que tabla usar?...
Pregunto:

1- ¿En que versión de Delphi esta desarrollada tu aplicación?.

2- ¿Que versión de Windows y Configuración de System Locale utiliza la máquina que envía la secuencia?.

3- ¿Que versión de Windows y Configuración de System Locale utiliza la máquina que recibe la secuencia?.

Espero sea útil

Nelson.
Responder Con Cita
  #6  
Antiguo 23-09-2013
Avatar de gatosoft
[gatosoft] gatosoft is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Bogotá, Colombia
Posts: 833
Poder: 22
gatosoft Va camino a la fama
Creo, (y supongo que es evidente) que el problema se da por la transformación de un texto desde UTF8 a ASCII... estas transportando, cargando un texto que VES en ASCII pero que te ha sido entregado en otro formato... tu lo recibes en ASCII y lo tratas como ASCII... y todo tu codigo está pensado en ASCII...

A mi me sucedia algo parecido, al crear un documento de TEXTO en Notepad++... Cuando lo leia en Delphi con un TStringList me mostraba éstos carateres extraños...

Código Delphi [-]
Var Cadena:String;
MyStringList.LoadFromFile(NombreArchivo);
Cadena:= MyStringList.Text;

lo que sucedía era que el archivo se estaba guardando en UTF8.. para esto Delphi da una solución

Código Delphi [-]
Var Cadena:String;
MyStringList.LoadFromFile(NombreArchivo,TEncode.UTF8);
Cadena:= MyStringList.Text;

Y listo..!!

A pesar que las variables String aceptan por defecto (ahora) carcateres unicode, el TStringList le estaba enviando algo que creia era ASCII...

saludo,
Responder Con Cita
  #7  
Antiguo 24-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Cita:
Empezado por nlsgarcia Ver Mensaje
Pregunto:

1- ¿En que versión de Delphi esta desarrollada tu aplicación?.

2- ¿Que versión de Windows y Configuración de System Locale utiliza la máquina que envía la secuencia?.

3- ¿Que versión de Windows y Configuración de System Locale utiliza la máquina que recibe la secuencia?.
1. Delphi 2010
2. Windows 7 64 (España, Internacional)
3. Ni idea, puede ser cualquiera, incluso linux, el cliente remoto es eso, un cliente remoto, yo creo un servidor TCP y a mi aplicación se le hacen consultas, por ejemplo (Lista de usuarios, Nombres de máquinas, estado de máquina tal o cual, etc) por eso, la mayoria (o todos) esperan una secuencia ASCII
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.

Última edición por cesarsoftware fecha: 24-09-2013 a las 11:15:46.
Responder Con Cita
  #8  
Antiguo 24-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Cita:
Empezado por gatosoft Ver Mensaje
Creo, (y supongo que es evidente) que el problema se da por la transformación de un texto desde UTF8 a ASCII... estas transportando, cargando un texto que VES en ASCII pero que te ha sido entregado en otro formato... tu lo recibes en ASCII y lo tratas como ASCII... y todo tu codigo está pensado en ASCII...

A mi me sucedia algo parecido, al crear un documento de TEXTO en Notepad++... Cuando lo leia en Delphi con un TStringList me mostraba éstos carateres extraños...

Código Delphi [-]Var Cadena:String; MyStringList.LoadFromFile(NombreArchivo); Cadena:= MyStringList.Text;


lo que sucedía era que el archivo se estaba guardando en UTF8.. para esto Delphi da una solución

Código Delphi [-]Var Cadena:String; MyStringList.LoadFromFile(NombreArchivo,TEncode.UTF8); Cadena:= MyStringList.Text;


Y listo..!!

A pesar que las variables String aceptan por defecto (ahora) carcateres unicode, el TStringList le estaba enviando algo que creia era ASCII...

saludo,
Algo asi debe ser, pero .... este es el código de la función que uso (pero también está este problema EN TODO DELPHI 2010).
Por cierto, uso asnsistring porque cada caracter es de 8 bit, si uso string cada carácter es de 16 bit, que ya me las he tenido que ver con Delphi 2010 por este tema.
Código Delphi [-]
function ThreadReadServidor.Envia(cadena: ansistring): integer;
var
  size: word;
  Resultado, sendlen, slen: integer;
begin
  slen := Sizeof(remoto);
  Resultado := 0;
  size := Length(cadena);
  if size = 0 then
  begin
    Result := -6;
    Exit;
  end;
  if tipo = UDP then
    sendlen := SendTo(nSocket, cadena[1], size, 0, remoto, slen)
  else
    sendlen := Send(nSocket, cadena[1], size, 0);
  if (sendlen = SOCKET_ERROR) or (sendlen < size) then
  begin
    case WSAGetLastError of
      WSANOTINITIALISED: ErrorString := 'A successful WSAStartup call must occur before using this function.';
      WSAENETDOWN: ErrorString := 'The network subsystem has failed.';
      WSAEACCES: ErrorString := 'The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST socket option to enable use of the broadcast address.';
      WSAEINTR: ErrorString := 'A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.';
      WSAEINPROGRESS: ErrorString := 'A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.';
      WSAEFAULT: ErrorString := 'The buf parameter is not completely contained in a valid part of the user address space.';
      WSAENETRESET: ErrorString := 'The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.';
      WSAENOBUFS: ErrorString := 'No buffer space is available.';
      WSAENOTCONN: ErrorString := 'The socket is not connected.';
      WSAENOTSOCK: ErrorString := 'The descriptor is not a socket.';
      WSAEOPNOTSUPP: ErrorString := 'MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.';
      WSAESHUTDOWN: ErrorString := 'The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.';
      WSAEWOULDBLOCK: ErrorString := 'The socket is marked as nonblocking and the requested operation would block.';
      WSAEMSGSIZE: ErrorString := 'The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.';
      WSAEHOSTUNREACH: ErrorString := 'The remote host cannot be reached from this host at this time.';
      WSAEINVAL: ErrorString := 'The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.';
      WSAECONNABORTED: ErrorString := 'The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.';
      WSAECONNRESET: ErrorString := 'The virtual circuit was reset by the remote side executing a hard or abortive close. For UDP sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet.';// The application should close the socket as it is no longer usable.';
      WSAETIMEDOUT: ErrorString := 'The connection has been dropped, because of a network failure or because the system on the other end went down without notice.';
    else
      ErrorString := 'Error Desconocido';
    end;
    Resultado := -7;
  end;
  Result := Resultado;
end;
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #9  
Antiguo 24-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Es esta función no puedo selecionar una tabla de conversión, necesito enviar en ASCII y no te digo nada cuando el cliente remoto es un control numérico CNC de hace 20 años que vete tu a saber que SO lleva sino es un SO propietario, lo que si se es que lo normal es que esperen caracteres ASCII.

He intentado convertir la cadena: ansistring recibida a otro tipo como decia al principio de este post para tampoco he solucionado el tema. ¿Como puedo convertir la cadena recibida en una cadena ASCII?
String, ShortString, AnsiString, UnicodeString, WideString parece que son UTF8 en Delphi 2010.
Aunque pensandolo bien, si la cadena ya se ha generado en UTF8 no voy a poder convertirla nunca, debo crear la cadena original en ASCII ¿Como se hace esto? no he visto nada en la ayuda de Delphi 2010

Thanks
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.

Última edición por cesarsoftware fecha: 24-09-2013 a las 11:10:08.
Responder Con Cita
  #10  
Antiguo 24-09-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cesarsoftware,

Cita:
Empezado por cesarsoftware
...creo un servidor TCP y a mi aplicación se le hacen consultas...

...vete tu a saber que SO lleva...puede ser cualquiera, incluso linux...sino es un SO propietario...el cliente remoto es eso, un cliente remoto...lo que si se es que lo normal es que esperen caracteres ASCII...

...si la cadena ya se ha generado en UTF8 no voy a poder convertirla nunca...
Te comento:

1- Sería conveniente saber cuales son las características del cliente remoto que presenta el problema mencionado en el Msg #1, quizás con mayor información podamos acotar el problema de forma más precisa.

2- ¿Has probado el tipo de dato UTF8String y la función de conversión Utf8ToAnsi?, la idea es manejar los datos a enviar en el Servidor como UTF8String y convertirlos a ASCII por medio de Utf8ToAnsi al momento del envío.

Revisa esta información:
Cita:
Empezado por Delphi Object and Component Reference
UTF8String represents a string in the UTF-8 character set, UTF8String is the type for strings encoded using UTF-8. UTF-8 is an efficient encoding of Unicode character-strings that recognizes the fact that the majority of text-based communications are in ASCII, and optimizes the encoding of these characters.
3- Quizás el problema esta relacionado al CodePage del Sistema Receptor, la tabla ASCII varía según el mismo, por ejemplo el CodePage 437 se corresponde con la siguiente tabla: El codigo ASCII, la cual se adapta a lo esperado por el Servidor según lo comentado en el Msg #1, pregunto: ¿Y si el CodePage fuera otro cualquiera?, revisa este link : Code Page Identifiers

4- Revisa este código:
Código Delphi [-]
function ChangeCodePage(const InputStr: AnsiString; CodePage : Integer): AnsiString;
var
   AuxStr: WideString;

begin

   AuxStr := WideString(InputStr);

   SetLength(Result, WideCharToMultiByte(CodePage, 0, PWideChar(InputStr),
            Length(InputStr), nil, 0, nil, nil));

   WideCharToMultiByte(CodePage, 0, PWideChar(AuxStr), Length(AuxStr),
                       PAnsiChar(Result), Length(Result), nil, nil);

end;
El código anterior convierte un String a un AnsiString con un CodePage específico, quizás puedas probar enviando los datos como CodePage 437.

Revisa este link:
Cita:
WideCharToMultiByte function : http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
Pregunto:

1- ¿El problema se presenta con más de un cliente remoto?.

2- ¿Hay clientes remotos con los que funciona bien la transferencia?.

3- ¿Has considerado normalizar todos los datos eliminado los caracteres acentuados por sus correspondientes sin acento?.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 24-09-2013 a las 15:46:10.
Responder Con Cita
  #11  
Antiguo 25-09-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cesarsoftware,

Cita:
Empezado por cesarsoftware
...¿Como puedo hacer que use la tabla "normal"?...
Cita:
Empezado por nlsgarcia
...Quizás el problema esta relacionado al CodePage del Sistema Receptor...
Revisa este código:
Código Delphi [-]
// Definiendo un String con un CodePage determinado
procedure TForm1.Button1Click(Sender: TObject);
type

   // CodePage 437 OEM - United States
   USAString = type AnsiString(437);

   // CodePage 28591 ISO 8859-1 Latin I
   LatinIString = type AnsiString(28591);

var
   StrUSA : USAString;
   StrLatinI : LatinIString;
   i : Integer;
   S1, S2 : AnsiString;

begin

   Memo1.Clear;

   StrUSA := 'César';
   S1 := EmptyStr;
   S2 := EmptyStr;

   for i := 1 to Length(StrUSA) do
      S1 := S1 + IntToStr(Ord(StrUSA[i])) + ',';

   S2 := 'Value StrUSA = ' + StrUSA + ',' + ' CodePage = ' + IntToStr(StringCodePage(StrUSA)) +
         ',' + ' Ordinal StrUSA= ' + S1;

   Memo1.Lines.Add(S2);

   StrLatinI := 'César';
   S1 := EmptyStr;
   S2 := EmptyStr;

   for i := 1 to Length(StrLatinI) do
      S1 := S1 + IntToStr(Ord(StrLatinI[i])) + ',';

   S2 := 'Value StrLatinI = ' + StrLatinI + ',' + ' CodePage = ' + IntToStr(StringCodePage(StrLatinI)) +
         ',' + ' Ordinal StrLatinI = ' + S1;

   Memo1.Lines.Add(S2);

end;
El código anterior en Delphi 2010, define un tipo de string asociado a un codepage particular, lo cual permitirá enviar la información del Servidor al Cliente Remoto en función del formato requerido en el Msg #1 por medio del CodePage 437, según se muestra en la siguiente imagen:



Revisa este link:
Cita:
Understanding Unicode Support in Delphi : http://delphi.about.com/od/objectpas...-in-delphi.htm
Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 25-09-2013 a las 02:04:51.
Responder Con Cita
  #12  
Antiguo 05-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Buenos días nelson.

Perdona por no haber respondido antes, tu esfuerzo se merece una pronta respuesta, pero por suerte he estado todas la semana muy liado con unas ventas nuevas

Tus respuestas tienen toda la pinta de ser lo que necesito, usar el codepage 437 porque soy yo el que emite un codigo incorrecto para lo esperado 233 en vez de 130. No te tenido tiempo de implementar la función, espero poder hacerlo esta tarde y te comento.

Gracias.
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #13  
Antiguo 05-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Cita:
Empezado por nlsgarcia Ver Mensaje
Pregunto:

1- ¿El problema se presenta con más de un cliente remoto?.

2- ¿Hay clientes remotos con los que funciona bien la transferencia?.

3- ¿Has considerado normalizar todos los datos eliminado los caracteres acentuados por sus correspondientes sin acento?.

Espero sea útil

Nelson.
1. Si, en todos
2. No, en ninguno
Es decir, yo emito mal el carácter como te comentaba en el post anterior.
3. Imposible, es el usuario el que define los nombres, el ejemplo de "César" es porque detecte el fallo usando mi propio nombre como ejemplo.

Gracias de nuevo.
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #14  
Antiguo 09-10-2013
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 915
Poder: 23
cloayza Tiene un aura espectacularcloayza Tiene un aura espectacular
Cita:
Empezado por cesarsoftware Ver Mensaje
3. Imposible, es el usuario el que define los nombres, el ejemplo de "César" es porque detecte el fallo usando mi propio nombre como ejemplo.Gracias de nuevo.
Talvez la solución sería que te cambies el nombre..
Responder Con Cita
  #15  
Antiguo 09-10-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cesarsoftware,

Cita:
Empezado por cesarsoftware
...No te tenido tiempo de implementar la función, espero poder hacerlo...y te comento...
Pregunto: ¿Pudistes probar la solución sugerida en el Msg #11?.

Espero sea útil

Nelson.
Responder Con Cita
  #16  
Antiguo 09-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Buenos días Nelson.

Implemente la función ChangeCodePage de forma que si al objeto TServidorSocket de le indica un codepage entonces la usa,
Código Delphi [-]
function TServidorSocket.Envia(cadena: ansistring): integer;
var
  size: word;
  Resultado, sendlen: integer;
  cadena437: ansistring;
begin
  Resultado := 0;
  if CodePage = 0 then
    cadena437 := cadena
  else
    cadena437 := ChangeCodePage(cadena, 437);
  size := Length(cadena437);
  if size = 0 then
  begin
    Result := -8;
    Exit;
  end;
  sendlen := Send(nSocket, cadena437[1], size, 0);
  if (sendlen = SOCKET_ERROR) or (sendlen < size) then
  begin
    case WSAGetLastError of
      WSANOTINITIALISED: ErrorString := 'A successful WSAStartup call must occur before using this function.';
      WSAENETDOWN: ErrorString := 'The network subsystem has failed.';
      WSAEACCES: ErrorString := 'The requested address is a broadcast address, but the appropriate flag was not set. Call setsockopt with the SO_BROADCAST socket option to enable use of the broadcast address.';
      WSAEINTR: ErrorString := 'A blocking Windows Sockets 1.1 call was canceled through WSACancelBlockingCall.';
      WSAEINPROGRESS: ErrorString := 'A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.';
      WSAEFAULT: ErrorString := 'The buf parameter is not completely contained in a valid part of the user address space.';
      WSAENETRESET: ErrorString := 'The connection has been broken due to the keep-alive activity detecting a failure while the operation was in progress.';
      WSAENOBUFS: ErrorString := 'No buffer space is available.';
      WSAENOTCONN: ErrorString := 'The socket is not connected.';
      WSAENOTSOCK: ErrorString := 'The descriptor is not a socket.';
      WSAEOPNOTSUPP: ErrorString := 'MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication domain associated with this socket, or the socket is unidirectional and supports only receive operations.';
      WSAESHUTDOWN: ErrorString := 'The socket has been shut down; it is not possible to send on a socket after shutdown has been invoked with how set to SD_SEND or SD_BOTH.';
      WSAEWOULDBLOCK: ErrorString := 'The socket is marked as nonblocking and the requested operation would block.';
      WSAEMSGSIZE: ErrorString := 'The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.';
      WSAEHOSTUNREACH: ErrorString := 'The remote host cannot be reached from this host at this time.';
      WSAEINVAL: ErrorString := 'The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE enabled.';
      WSAECONNABORTED: ErrorString := 'The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable.';
      WSAECONNRESET: ErrorString := 'The virtual circuit was reset by the remote side executing a hard or abortive close. For UDP sockets, the remote host was unable to deliver a previously sent UDP datagram and responded with a "Port Unreachable" ICMP packet.';// The application should close the socket as it is no longer usable.';
      WSAETIMEDOUT: ErrorString := 'The connection has been dropped, because of a network failure or because the system on the other end went down without notice.';
    else
      ErrorString := 'Error Desconocido';
    end;
    Resultado := -9;
    Finaliza();
  end;
  Result := Resultado;
end;
Y lo curioso es que en la aplicación que me hacia falta funciono Gracias.
Pero al ser un objeto que uso en otras aplicaciones, probar en otra con algunos mensajes como "Máquina no encontrada" y no funciona

¿Se puede especificar un codepage para toda la aplicación? He visto en propiedades del proyecto "Compiling" y "Resource compiling" el valor para codepage, he puesto en ambos casos 437 y no noto diferencia, también está la opción "Version info" la posiblididad de definir el "Locale ID" pero tampoco veo resultado.

Asi que de momento mejor que antes ya estoy. Gracias.
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #17  
Antiguo 09-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Tambien en probado con esto
Código Delphi [-]
type
   string437 = type AnsiString(437);
   function ExtraeGolpesDeMaquina(nombre: string; senal: word): string437;
Código Delphi [-]
function TFormMain.ExtraeGolpesDeMaquina(nombre: string; senal: word): string437;
var
  i: word;
  maquina: integer;
  res: string437;
begin
  maquina := BuscaIndiceDeMaquina(nombre);
  if maquina = -1 then
  begin
    res := String437('[3,' + nombre + ',Máquina no encontrada]');
    Result := res;
    Exit;
  end;
  res := '[0,';
  if senal = 0 then
  begin
    // todos los golpes
    for i := 0 to 5 do
      res := res + String437(IntToStr(DCx[maquina].Contadores[i])) + ',';
    res := Copy(res, 1, Length(res) - 1); // quitarle ultima coma
  end
  else
  begin
    if (senal < 1) or (senal > 6) then
      res := '[4,' + 'Señal fuera de rango'
    else
      res := res + String437(IntToStr(DCx[maquina].Contadores[senal - 1]));
  end;
  res := res + ']';
  Result := res;
end;

Y la uso asi
Código Delphi [-]
  if comando = 'golpes' then
  begin
    msg := ExtraeGolpesDeMaquina(parametro, senal);
    TServidorSocket(Sender).rxClientes[rxCliente].Envia(AnsiString(msg));
  end;

Y al pasar por la funcion del mensaje anterior, he probado a que convierta a 437 y el tipo no es String437 y que la deje tal cual si el tipo si es String437, y en esta aplicación no funciona.
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #18  
Antiguo 09-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
incluso he probado esto
Código Delphi [-]
msg:string437;
  TServidorSocket(Sender).rxClientes[rxCliente].Envia(msg);

function ThreadReadServidor.Envia(cadena: string437): integer;
y tampoco, estoy confundido
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
  #19  
Antiguo 09-10-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 21
nlsgarcia Tiene un aura espectacularnlsgarcia Tiene un aura espectacular
cesarsoftware,

Cita:
Empezado por cesarsoftware
...Implemente la función ChangeCodePage...en la aplicación que me hacia falta funciono...
Excelente

Cita:
Empezado por cesarsoftware
...¿Se puede especificar un codepage para toda la aplicación?...
Si, es posible especificar un CodePage para toda la aplicación, revisa esta información:
Cita:
Empezado por ms-help://embarcadero.rs2010/rad/Compiling.html

Option : Proyect -> Options -> Delphi Compiler -> Compiling - Code Page


Enter the code page for your application's language, such as 1252. Code page is a decimal number representing a specific character encoding table, and there are standard values for various languages, Default = 0.
Revisa esta imagen:



Revisa este código relacionado a la imagen anterior:
Código Delphi [-]
// Definiendo un String con un CodePage determinado (28591) y CodePage de la Aplicación en 437
procedure TForm1.Button1Click(Sender: TObject);
type

  // CodePage 28591 ISO 8859-1 Latin I
  LatinIString = type AnsiString(28591);

var
   StrUSA : AnsiString;
   StrLatinI : LatinIString;
   i : Integer;
   S1, S2 : String;

begin

   Memo1.Clear;

   StrUSA := 'César';
   S1 := EmptyStr;
   S2 := EmptyStr;

   for i := 1 to Length(StrUSA) do
      S1 := S1 + IntToStr(Ord(StrUSA[i])) + ',';

   S2 := 'Value StrUSA = ' + StrUSA + ',' + ' CodePage = ' + IntToStr(StringCodePage(StrUSA)) +
         ',' + ' Ordinal StrUSA= ' + S1;

   Memo1.Lines.Add(S2);

   StrLatinI := 'César';
   S1 := EmptyStr;
   S2 := EmptyStr;

   for i := 1 to Length(StrLatinI) do
      S1 := S1 + IntToStr(Ord(StrLatinI[i])) + ',';

   S2 := 'Value StrLatinI = ' + StrLatinI + ',' + ' CodePage = ' + IntToStr(StringCodePage(StrLatinI)) +
         ',' + ' Ordinal StrLatinI = ' + S1;

   Memo1.Lines.Add(S2);

end;
El código anterior utiliza el Codepage 437 definido a nivel de la aplicación por medio del tipo AnsiString, como se puede ver en la siguiente imagen:



Te sugiero usar el CodePage 437 a nivel de la aplicación por medio del tipo AnsiString, el cual reflejara el CodePage definido a nivel de la aplicación, como se indica en las imágenes y en el código del ejemplo y permitirá enviar la información del Servidor al Cliente Remoto en función del formato requerido en el Msg #1.

Nota: El CodePage a nivel de la aplicación solo aplica por medio del tipo AnsiString.

Espero sea útil

Nelson.

Última edición por nlsgarcia fecha: 09-10-2013 a las 19:26:45.
Responder Con Cita
  #20  
Antiguo 09-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 18
cesarsoftware Va por buen camino
Muchisimas gracias nelson,

Creo que cuando prove el codepage a nivel de aplicación, usaba el tipo string, pero lo pruebo ahora mismo y te cuento si funciona en la segunda aplicación, pero si es asi a partir ed ahora codepage 437 para todos los nuevos proyectos, porque .... El Ascii de toda la vida es el 437 ¿o estoy mu anticuado?
__________________
Disfruta de la vida ahora, vas a estar muerto mucho tiempo.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
insert ansistring? noelr Conexión con bases de datos 0 23-11-2011 02:00:59
Uso de AnsiString 11_8_88 C++ Builder 8 14-08-2010 20:53:47
Generar un string con codigos ascii JordiP Varios 9 16-12-2009 11:39:16
string o AnsiString? javier20 OOP 1 19-08-2007 01:58:35
AnsiString en una Dll Trigger API de Windows 2 21-01-2004 22:53:20


La franja horaria es GMT +2. Ahora son las 15:40:57.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi