Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Coloboración Paypal con ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 24-09-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 20
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
  #2  
Antiguo 24-09-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 23
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
  #3  
Antiguo 25-09-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 23
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
  #4  
Antiguo 05-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 20
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
  #5  
Antiguo 05-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 20
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
  #6  
Antiguo 09-10-2013
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 948
Poder: 25
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
  #7  
Antiguo 09-10-2013
Avatar de nlsgarcia
[nlsgarcia] nlsgarcia is offline
Miembro Premium
 
Registrado: feb 2007
Ubicación: Caracas, Venezuela
Posts: 2.206
Poder: 23
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
  #8  
Antiguo 09-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 20
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
  #9  
Antiguo 09-10-2013
Avatar de cesarsoftware
cesarsoftware cesarsoftware is offline
Miembro
 
Registrado: nov 2006
Posts: 241
Poder: 20
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
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

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 06:28:50.


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