Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi problem mit tserversocket - sendtext client-id (https://www.delphipraxis.net/143250-problem-mit-tserversocket-sendtext-client-id.html)

painrestricter 12. Nov 2009 14:08


problem mit tserversocket - sendtext client-id
 
servuß

ich bin dabei einen kleinen chat zu schreiben, wie wahrscheinlich jeder am anfang ^^

funktioniert auch schon soweit alles, verbindung steht, text kann gesendet werden usw.
ABER: ich kann nur vom clienten zum server eine nachricht schicken, aber nicht vom server zum clienten.

ich such das problem jetzt schon die ganze zeit, kanns aber nicht finden.

Wenn ich vom server aus eine nachricht(bzw nen text) zum clienten schicken will, kommt:

Delphi-Quellcode:
Windows-Socket-Fehler: Eine anforderung zum senden oder empfangen von daten wurde verhindert, da der socket nicht verbunden ist und (beim senden über einen datagrammsocket mit sento-aufruf) keine adresse angegeben wurde (10057), auf API 'send'
wtf? die verbindung steht aber.

hier mal der source vom server:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
serversocket1.Active := true;
serversocket1.Port := strtoint(edit1.text);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
memo1.clear;
edit1.text := '6900';
memo1.lines.add('----Welcome----');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
serversocket1.Active := false;
Application.Terminate;
end;

procedure TForm1.ServerSocket1ClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
showmessage('An Error occurred while connecting, try again');
errorcode := 0;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
// nur zahlen erlauben
if not (key in ['0'..'9', char(vk_back)]) then
 key := #1;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Memo1.Lines.add('Connected: welcome :) ');
Memo1.lines.add('-------------------');
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo1.lines.Add(socket.ReceiveText);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
serversocket1.Socket.SendText(edit2.text);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
serversocket1.Close;
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo1.lines.add('status: Disconnected');
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
MessageDlg('blabla', mtInformation , [mbOK] ,0);
end;

end.
ich bedanke mich jetzt schon für die hilfe :)
gruß

fui-tak 12. Nov 2009 14:44

Re: problem mit tserversocket
 
Hallo,
Ich glaube ich habe dein Problem gefunden

Um Daten vom Server zum Client zu schicken, muss man angeben an welchen Client die Daten sollen. Ein Server kann ja mehrere Clients haben. Das funktioniert dann so:
Delphi-Quellcode:
ServerSocket1.Socket.Connections[0].SendText('Hallo Welt');
In die eckigen Klammern kommt die Nummer des Clients rein, die Zählung fängt bei 0 an

painrestricter 12. Nov 2009 15:32

Re: problem mit tserversocket
 
fuitak, ich liebe dich :mrgreen: :mrgreen:

danke, jetzt gehts :)

wie kann ich dem clienten eine spezielle id zuweisen?
spontan fällt mir da vielleicht das ein

var id: array [0..10] of integer;

uoeb7gp 12. Nov 2009 15:36

Re: problem mit tserversocket
 
Hi, außerdem ist die Übermittlung des Textes nur solange sicher, solange der gesamte Text auf einmal in den Empfangsbuffer
des Empfänger Sockets paßt, also nicht in mehreren Stücken übermittelt werden muß.
Deshalb brauchst Du auch noch einen Daten-Header, der die Längeninfos des übermittelten Textes enthält.

Als Beispiel:

{GENERIC HEADER}
//-- Headeraufbau MsgID = Byte = 0..255; Msg-Length = DWORD

//-- +--------------------|--------------------------|----------------+
//-- | Byte-MsgID | 4Byte-DWORD Msg-Length | Daten |
//-- +--------------------|--------------------------|----------------+

Der Empfänger Socket, extrahiert beim Empfangen die ersten 5 Bytes aus der Message, und liest
Solange aus dem Socket bis alle Daten übertragen wurde.

fui-tak 12. Nov 2009 15:39

Re: problem mit tserversocket
 
Zitat:

Zitat von painrestricter
wie kann ich dem clienten eine spezielle id zuweisen?
spontan fällt mir da vielleicht das ein
var id: array [0..10] of integer;

Also diesen Index, den man in "ServerSocket1.Socket.Connections[0].SendText('Hallo Welt');" reinschreibt kann man einen Client nicht zuweisen, den bekommt er automatisch.
Der erste angemeldete Client bekommt Nummer 0, der zweite bekommt die 1 usw.
Wenn sich dann z.B. der erste Client abmeldet, dann bekommt der ursprünglich zweite die Nummer 0, es wird also nachgerückt

So jetzt muss ich aber los, also erstmal viel Spaß hiermit :bounce1:

uoeb7gp 12. Nov 2009 15:42

Re: problem mit tserversocket
 
Im Read der Komponente kriegst alles mit wast brauchst!

Delphi-Quellcode:
procedure TServerObj.ServerSocketClientRead(const Sender: TObject;
  const Socket: TCustomWinSocket);
var
  cbRcv: integer;
  RcvBuf: array [0..WSOCK_READ_BUFFER_SIZE * 8] of Byte;
  RcvBufItem: TRcvBufItem;
  hMemData: hGlobal;
  hMemStruct: hGlobal;
begin
  cbRcv := Socket.ReceiveBuf(RcvBuf[0], WSOCK_READ_BUFFER_SIZE * 8);
  if cbRcv <= 0 then EXIT;

  if Socket.SocketHandle <= 0 then EXIT;

  hMemData := GlobalAlloc(GMEM_FIXED, cbRcv);
  move(RcvBuf[0], Pointer(hMemData)^, cbRcv);

  hMemStruct := GlobalAlloc(GMEM_FIXED, SizeOf(TRcvBufItem));

  RcvBufItem.ptrData   := Pointer(hMemData);
  RcvBufItem.cbData    := cbRcv;
  RcvBufItem.Socket    := Socket.SocketHandle;
  RcvBufItem.hMemStruct := hMemStruct;
  RcvBufItem.hMemData  := hMemData;

  move(RcvBufItem, Pointer(hMemStruct)^, SizeOf(TRcvBufItem));

  if FRecvBuffer.Write(Pointer(hMemStruct), SizeOf(TRcvBufItem)) <>
    SizeOf(TRcvBufItem) then
  begin
    FRecvBuffer.SetBufSize((FRecvBuffer.BufSize + cbRcv) * 2);
    FRecvBuffer.Remove(SizeOf(TRcvBufItem));
    if FRecvBuffer.Write(Pointer(hMemStruct), SizeOf(TRcvBufItem)) <>
      SizeOf(TRcvBufItem) then
        raise exception.Create('you should never see this');
  end;
 
  SetEvent(FMsgDispatchEvent);
end;

fui-tak 12. Nov 2009 18:00

Re: problem mit tserversocket
 
Hui der Code sieht aber sehr kompliziert aus... und da unser guter painrestricter, zumindest in Sachen Socket-Programmierung, noch Neuling ist, wäre es doch eigentlich schön mal zu sagen, was diese Methode eigentlich genau macht

SirThornberry 12. Nov 2009 18:13

Re: problem mit tserversocket
 
@painrestricter: Könntest du deinem Beitrag bitte einen aussagekräftigeren Titel geben? Das es sich um ein Problem handelt sagt bereits das gewählte Forum aus und "TServersocket" sagt nicht aus was für ein Problem du damit hast.
Ein aussagekräftiger Titel hat den Vorteil das andere mit dem gleichen Problem dieses Thema später über die Suche besser finden und somit hoffentlich auch die Lösung.
Zudem hat es für dich den Vorteil das Leute anhand des Titels sofort wissen ob sie helfen können oder nicht. Nicht jeder hat Zeit alle Themen durchzulesen und wenn der Titel aussagekräftig ist und somit jemand sofort weiß das er helfen kann profitierst du vor allem davon. :)

painrestricter 12. Nov 2009 23:19

Re: problem mit tserversocket - sendtext client-id
 
erledigt, SirThornberry


uoeb7gp, danke für den code, aber wie fui-tak schon sagt, ich kann mit den code weder umgehen noch was damit anfangen. ABER es interessiert mich, also werd ich den mal genauer anschauen.

Könnte ich theoretisch auch das customwinsocket modifizieren?

uoeb7gp 13. Nov 2009 16:05

Re: problem mit tserversocket - sendtext client-id
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also anbei der src.
Es handelt sich dabei um eine Implementierung eines Hocklast-Async Socket Servers.

Features:
send und recv buffered and threaded.

Server und Client DLL wurden auf höchsten Durchsatz und Performance hin ausgelegt.
Gegenüber der damaligen JAVA Implementierung stieg die Performance um nahezu 600% !!!!!

Have a lot of Fun.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz