Entwickler-Ecke

Internet / Netzwerk - Empfangene Packete verarbeiten


Flamefire - Di 11.08.09 18:30
Titel: Empfangene Packete verarbeiten
Ich habe eine WS-Wrapper Klasse geschrieben, die mir Packete empfangen und weiterverarbeiten soll.
dazu diese Function:
PacketStruktur ist:
Word:Länge der Daten (ohne Header) in Byte
Word:OpCode
Word:CRC (not used here)
dann die Daten

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
class procedure TClient.HandlePacket;
var size,curSize,bfSize,curPos:Integer;
    encrypted:boolean;
begin
  curSize:=Length(Buffer);
  SetLength(Buffer,curSize+8193);
  Winsockread(sockClient,@buffer[curSize],size);
  if(size<=0then begin
    SetLength(Buffer,curSize);
    exit;
  end;
  curSize:=curSize+size;
  SetLength(Buffer,curSize);
  curPos:=0;
  while(curPos+6<=curSize) do begin
    size:=PWord(@Buffer[curPos])^;
    if(curPos+6+size>curSize) then break;
    DispatchPacket(PWord(@buffer[curPos+2])^,Word(size),Cardinal(@buffer[curPos+6]));//Params sind: Opcode,Länge,Daten
    InjectPacket(@buffer[curPos]);//sendet Daten weiter
    Inc(curPos,size+6);
  end;
  SetLength(Buffer,curSize-curPos);
end;

Buffer ist eine Klassenvariable mit "Array of Byte"
sollte so korrekt sein, oder?
will damit praktisch unvollständig packete und mehrere packete im buffer managen

2. teil:
Der Message Handler ist ein class(TForm) mit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
//...
    procedure MessageHandler(var Msg:TMessage);Message MSG_ASYNC;
//...
procedure TWS.MessageHandler(var msg:Tmessage);
begin
  case WSAGetSelectEvent(MSG.LParam) of
    FD_READ: TClient.HandlePacket;

    FD_CLOSE: //...

    FD_ACCEPT: //...
  end;
end;
//...
procedure TWS.Initialize(port:integer);
begin
//Initialize
  if not WSInitialized then Exit;

//Setup the sockets for sro_client
  LsockClient:=WinsockBind(port);
  if not(WinsockListen(LsockSRClient)) then Exit;
  TieSocket(WS.Handle,LsockClient,MSG_ASYNC);
end;
//...
class procedure TWS.TieSocket(handle:hwnd;Sock:TSocket;Msg:Integer);
begin
// Set asynchronous mode on the socket
  dwError:=WSAAsyncSelect(Sock, handle, Msg, FD_CLOSE or FD_READ or FD_ACCEPT);
   if dwError <> ERROR_SUCCESS then
  begin
    dwError:=WSAGetLastError;
//...
    CloseSocket(Sock);
    Exit;
  end;
end;

Könne hier Probleme auftreten?
Meine Probleme derzeit:
Das Programm hat eine Gui, die gelegendlich mal einfriert (vermutlich beim Warten auf eine Verbindung).
Muss ich also das Form TWS in einem ExtraThread erzeugen?
Außerdem habe ich das Problem, dass wenn ich in der HandlePacket function eine showmessage() zeige, läuft die Funktion erneut an.
Soll heißen: Die funktion wird nochmal aufgerufen, obwohl noch die MessageBox offen ist!
Wie geht das?
die nachrichtenschleife wird doch erst weiterlaufen, wenn die Funktion beendet ist, oder?

Zusätzlich: Eigendlich brauche ich das Form TWS ja gar nicht
ich könnte ja einfach ein "Fenster" ohne Fenster machen, um ein Handle zu haben, und das dann in einer Nachrichtenschleife abfragen.
Aber wie geht das? Hat da jemand ein bischen Code oder nen Link?