AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Server-Disconnect erkennen (WinSock)
Thema durchsuchen
Ansicht
Themen-Optionen

Server-Disconnect erkennen (WinSock)

Ein Thema von dde · begonnen am 14. Dez 2004 · letzter Beitrag vom 19. Dez 2004
 
dde

Registriert seit: 7. Mai 2003
132 Beiträge
 
#2

Re: Server-Disconnect erkennen (WinSock)

  Alt 18. Dez 2004, 12:34
Hab mich jetzt weiter mit diesem Thema beschäftigt und bin auf WSAAsyncSelect() (WinSock-Funktion) gestoßen.

Die MSDN sagt folgendes zu dieser Funktion:

Zitat:
The WSAAsyncSelect function requests Windows message-based notification of network events for a socket.

int WSAAsyncSelect(
SOCKET s,
HWND hWnd,
unsigned int wMsg,
long lEvent
);
Also habe ich das wie folgt implementiert:

Hauptprogramm:

Delphi-Quellcode:
program Project1;

uses
  Windows,
  WinSock,
  messages,
  uServer in 'uServer.pas';
var
  S:TServer;

function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM;
lParam: LPARAM): LRESULT; stdcall;
var
begin
  Result := 0;
  case Msg OF
    WM_SOCKET: //Konstante in uServer
      begin
        if Assigned(S) then
         if LParam=FD_CLOSE then S.Disconnect;
         {...}
      end;
  else
    Result := DefWindowProc(hWnd, Msg, wParam, lParam);
  end;
end;

var
  msg:TMsg;
begin
S:=TServer.Create(1223);
with S do
 begin
  Listen;
  if not Listening then
   begin
    Free;
    S:=nil;
   end;
 end;

while true do
 begin
  if not GetMessage(Msg,0,0,0) then Break;
  DispatchMessage(Msg);
 end;
end.
Zunächst einmal gibt es hier das Problem, dass WndProc von DispatchMessage nicht aufgerufen wird, da WndProc keinem Handle zugewiesen ist. Ich will das ohne Handle machen...

So sieht nun uServer.pas aus:
Delphi-Quellcode:
unit uServer;

interface
uses Windows,Winsock,Messages;
const
WM_SOCKET = WM_USER;
FD_SERVER= FD_READ+FD_CONNECT+FD_CLOSE+FD_ACCEPT;

type
 TServer=class(TObject)

  constructor Create(xPort:Word);
  destructor Destroy; override;

  procedure Listen;
  procedure AcceptConnection;
  procedure Disconnect;

// procedure ExecuteMessage(var Msg:TMessage); message WM_SOCKET;

  private
   FSock:TSocket;
   FClientSock:TSocket;
   FPort:Word;
   FConnected:Boolean;
   FListening:Boolean;
  public
   property Sock:TSocket Read FSock;
   property ClientSock:TSocket Read FClientSock;
   property Port:Word Read FPort;
   property Connected:Boolean Read FConnected;
   property Listening:Boolean Read FListening;
 end;

implementation

constructor TServer.Create(xPort:Word);
begin
inherited Create;
FPort:=xPort;
FConnected:=False;
FListening:=False;
end;

destructor TServer.Destroy;
begin
if Connected then Disconnect;
WSACleanUP;
inherited Destroy;
end;

procedure TServer.AcceptConnection;
begin
if Connected then Exit;
FClientSock:=accept(Sock,nil,nil);
FConnected:=true;
end;

procedure TServer.Disconnect;
begin
shutdown(Sock,SD_SEND);
end;

procedure TServer.Listen;
var wsaData: TWSADATA;
    SockAddr: sockaddr_in;
begin
if (WSAStartup(MAKEWORD(2,0),WSAData)) <> 0 then Exit;

FSock:=Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if FSock = INVALID_SOCKET then Exit;

ZeroMemory(@SockAddr, sizeof(SockAddr));
SockAddr.sin_addr.S_addr := INADDR_ANY;
SockAddr.sin_family := AF_INET;
SockAddr.sin_zero := #0#0#0#0#0#0#0;
SockAddr.sin_port := htons(Port);

if (bind(Sock,SockAddr,SizeOf(SockAddr)))=SOCKET_ERROR then Exit;
if (WinSock.listen(Sock, 1)) = SOCKET_ERROR then Exit;
WSAAsyncSelect(Sock,0,WM_SOCKET,FD_SERVER);
FListening:=True;
end;

{procedure TServer.ExecuteMessage(var Msg:TMessage);
begin
end;}
Wie ihr vielleicht erkannt habt, habe ich ExecuteMessage hier ausgeklammert, da ich es zunächst über WndProc bewerkstelligen will.

Also TServer.Listen ruft am Ende die WSAASyncSelect() Funktion auf. Da diese Funktion ein Handle benötigt und ich kein Handle erzeugt habe, übergebe ich ihr die 0. WM_SOCKET ist die Message, die ankommen soll, wenn SOCK FD_SERVER, also entweder FD_READ, FD_CONNECT, FD_CLOSE oder FD_ACCEPT, zurückliefert.
Welches FD_XXX es endgültig ist, erfährt man entweder über lParam oder wParam der Message.

Nun zum Problem:
Es kommt keine Message WM_SOCKET an. Ich vermute es liegt am Handle=0, bin mir aber nicht sicher...
Wie krieg ich es hin, dass WndProc ohne Handle aufgerufen wird von DispatchMessage(Msg)? (eigntl. eine Win-Api Frage)

Habt ihr irgendwelche Ratschläge?
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz