Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 23-10-2008
Khronos Khronos is offline
Miembro
 
Registrado: abr 2007
Posts: 298
Poder: 18
Khronos Va por buen camino
Duda con sockets

Hola, estuve investigando como funcionan las sockets de windows y realicé este código. En una aplicación visual consigo realizar la aplicación cliente-servidor, pero desde una aplicación de consola no hay forma... si consigo que se conecte el cliente pero no soy capaz de recibir sus mensajes ni de enviarle nada

Código Delphi [-]
unit Server;

interface

uses Windows, WinSock, Messages, SysUtils, Classes;

const
  WM_WINSOCK_ASYNC_MSG = WM_USER + 2988;

  type
    TServer = class(TThread)
      private
        InitDllSock  : TWSAData;
        TCP: TSocket;
        WHandle: THandle;
        Msg: TMsg;
        Addr: TSockAddrIn;
      protected
        procedure AWndProc(  Msg: TMsg);
      public
        procedure SendStr(str: string);
        constructor Create; reintroduce;
        procedure Execute; override;
    end;


implementation

procedure TServer.SendStr(Str: string);
begin
 send(TCP, Pointer(Str)^, Length(Str), 0);
end;

procedure TServer.AWndProc( Msg: TMsg);
begin
   case WSAGetSelectEvent(Msg.lParam) of
   FD_ACCEPT:
    begin
    Writeln('Conexión entrante');
    SendStr('Hola cliente');
    end;
   FD_READ: Writeln('Leyendo..');
   FD_CLOSE: Writeln('Conexión cerrada');
 end;
end;

procedure TServer.Execute;
var
sinsize: integer;
begin
WSAStartup( $0202, InitDllSock );
TCP := socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
with addr do
  begin
    sin_family:= af_Inet;
    sin_port:= hToNs(1234);
    sin_addr.s_addr:= InAddr_Any;
  end;
bind(TCP, addr, SizeOf( addr ) );
//ioctlsocket( TCP, FIONBIO, 1);
WSAAsyncSelect(TCP, WHandle, WM_WINSOCK_ASYNC_MSG,
FD_READ or FD_CLOSE or FD_ACCEPT );
listen( TCP, 1);
while not Terminated do
    begin
      If GetMessage(Msg,WHandle, 0, 0) then
        begin
            TranslateMessage(Msg);
            Accept( TCP, @addr, @sinsize);
            DispatchMessage( Msg );
            AWndProc(Msg);
            Sleep(7000);
            SendStr('holaaaa');
        end;

    end;
end;

constructor TServer.Create;
begin
  inherited Create(True);
    FreeOnTerminate:= True;
    Execute;
end;


end.

Código Delphi [-]
program Servidor;

{$APPTYPE CONSOLE}

uses
  Server in 'Server.pas';

begin
TServer.Create;
end.

Saludos y gracias.
Responder Con Cita
  #2  
Antiguo 30-10-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
  1. El primer error que estas cometiendo es utilizar una variable que no es asignada (WHandle), por ello WSAAsyncSelect debería enviar los mensajes a la ventana con identificador 0, como esto es ilógico retorna error (SOCKET_ERROR).
  2. Es importante comprender que una aplicación de consola (como su nombre lo dice), es de tipo consola y no una ventana, por ende NO tiene una cola de mensajes y GetMessage entraría a un dead lock infinito. Para prevenir esto en una consola lo óptimo es crear una ventana la cual creará indirectamente la cola de mensajes.
  3. Cuando llamas al método del hilo dentro del mismo constructor del hilo (TThread) y sumado a esto el método tiene un loop, va a realizar una llamada directa tal cual si fuese cualquier otro método diferente a un hilo hasta que termine el loop. Lo que te esta dando la ilusión de que el hilo esta bien construido es que dentro del loop estas procesando la cola de mensajes (GetMessage -> TranslateMessage -> DispatchMessage) equivalente al Application.ProcessMessages. Para corroborar éste error y notar su gravedad prueba:
    Código Delphi [-]
    procedure TForm1.Button1Click(Sender: TObject);
    begin
     TServer.Create;
     ShowMessage('Never see me !')
    end;
    Considerando que esta falla es remediada hay un segundo problema GetMessage esperará un nuevo mensaje en la cola sin considerar la posibilidad de que el hilo sea terminado, esto puede causar la perdida de control en algunas situaciones.
  4. WSAStartup tiene la función de inicializar las funciones de sockets para el proceso ejecutor (~LoadLibrary ), esto debiese utilizarce cuando uno comenzará a utilizar los sockets y finalizarlo cuando uno termine, sin embargo en la mayoria de los sistemas éste tiempo es equivalente al tiempo de vida del proceso.
Aparte de MemoryLeaks y otros; aclaro que todo lo dicho fueron críticas constructivas a favor del conocimiento

Me temo que es complicado solucionar (para consola), dichas fallas, sin cambiar la escencia de dicho objeto (WSAAsyncSelect)

Saludos
__________________
RTFM > STFW > Foro > Truco > Post > cHackAll > KeBugCheckEx
Responder Con Cita
  #3  
Antiguo 30-10-2008
Khronos Khronos is offline
Miembro
 
Registrado: abr 2007
Posts: 298
Poder: 18
Khronos Va por buen camino
Muchas gracias cHackAll por tus consejos, voy a probar a crear una ventana dinamicamente con CreateWindowsEx para conseguir el handle de una ventana y poder caputar los mensajes.

Salu2
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
Duda de conección con Sockets Paulao Varios 4 08-07-2008 20:40:47
Uso de sockets vejerf Internet 3 15-11-2007 21:44:16
Sockets Caral Varios 4 29-08-2006 22:29:39
ADO y Sockets krilea Conexión con bases de datos 3 21-04-2005 22:38:55
Sockets con DB Slash Internet 1 08-07-2004 19:58:18


La franja horaria es GMT +2. Ahora son las 08:07:10.


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