Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Winsock , send/recv, wie? (https://www.delphipraxis.net/71649-winsock-send-recv-wie.html)

xxl1 18. Jun 2006 23:26


Winsock , send/recv, wie?
 
Hallo mitnander!
Ich möchte eine schlanken server und client programmieren die daten austauschen.
Kommuniziert wird über TCP also:
Delphi-Quellcode:
 S := socket (AF_INET, SOCK_STREAM , 0);
Es funktioniert alles bis auf die send/recv finktionen. Die Verbindung zwischen client und server steht(State= established),
dann will ich vom client zum server etwas senden:
Delphi-Quellcode:
function TNet_client.Winsock_sendTCP;
var bytecount:integer;
begin
  buffer:='Ein wichtiges Datenpaket';
  bytecount:=send(S, buffer, strlen(buffer), 0);
hier gibt mir WSAGetLastError 5 aus.
Delphi-Quellcode:
function TNet.Winsock_reciveTCP;
var datacount: integer;
begin
datacount:=recv(S, buffer, sizeof(buffer),0);
end;
hier wird mir für datacount -1 ausgegeben (Socket error)
und natürlich ist der buffer leer.
Weiss jemand wieso? Wenn ja, dann postet mal fleißig!
Danke schonmal!

Basilikum 19. Jun 2006 06:17

Re: Winsock , send/recv, wie?
 
ich nehme an, buffer ist bei dir PChar !?
Code:
function TNet_client.Winsock_sendTCP;
var bytecount:integer;
begin
  buffer:='Ein wichtiges Datenpaket';
  bytecount:=send(S, buffer[color=#ff001f]^[/color], strlen(buffer), 0);
(send() erwartet keinen Pointer, sondern eine untypiserte Variable)

zum 2. Problem: verrate uns doch noch, von welchem Type buffer ist... aller Pointer-ähnlichen Dinge scheiden aus, da du sizeof() verwendest...

xxl1 19. Jun 2006 17:11

Re: Winsock , send/recv, wie?
 
also wie du bereits vermutet hast, ist buffer : PChar in 1) und 2)
Daher jetzt die Frage: kann man bei einer Pchar Variable die funktion sizeof() nicht verwenden? Wenn ja , was kann man dann verwenden um die länge von Pchar zu ermitteln?

Basilikum 19. Jun 2006 17:55

Re: Winsock , send/recv, wie?
 
Zitat:

Zitat von xxl1
also wie du bereits vermutet hast, ist buffer : PChar in 1) und 2)
Daher jetzt die Frage: kann man bei einer Pchar Variable die funktion sizeof() nicht verwenden? Wenn ja , was kann man dann verwenden um die länge von Pchar zu ermitteln?

SizeOf() wird dir bei einem Pointer (PChar ist ein solcher) auf einer 32-Bit-Maschine immer 4 zurückgeben...
eine Möglichkeit ist StrLen(), dann ist es jedoch unmöglich, ein 0-Byte als Bestandteil der Daten zu haben, da dies als Kennzeichnung für das Ende dient... => kommt auf die Daten an - für "Nur-Text" funktioniert StrLen problemlos...

xxl1 19. Jun 2006 22:28

Re: Winsock , send/recv, wie?
 
ok danke für die Info ,hat leider nicht zum gewünschtrn Effekt geführt.

Nogge 20. Jun 2006 00:46

Re: Winsock , send/recv, wie?
 
Hallo xxl1,
Du musst nach dem Erstellen des Sockets natürlich erst mal zum Server connecten:
Delphi-Quellcode:
function TClient.Connect(const IP: string; Port: Word): Boolean;
var
  sa: SOCKADDR_IN;
  HostInfos : PHostEnt;
begin
  ZeroMemory(@sa, SizeOf(sa));
  sa.sin_family      := AF_INET;
  sa.sin_port        := htons(Port);
  sa.sin_addr.S_addr := inet_addr(PChar(IP));
  { nicht notwendig zum connecten
  HostInfos := gethostbyaddr(@sa.sin_addr.S_addr, SizeOf(sa.sin_addr.S_addr), AF_INET);
  if (HostInfos <> nil) then
    Hostname := HostInfos^.h_name;
  }
  Result := (WinSock.connect(FAccSock, sa, SizeOf(sa)) <> SOCKET_ERROR);
end;
Falls du das bereits getan hast, solltest du mithilfe der folgenden Funktion einen string übermitteln können:
Delphi-Quellcode:
// string
function TClient.Send(Data: string): Boolean;
begin
  Result := (WinSock.send(FAccSock, Data[1], Length(Data), 0) > 0); // SOCKET_ERROR = -1
end;
// PChar
function TClient.Send(Data: PChar): Boolean;
begin
  Result := (WinSock.send(FAccSock, Data[0], Length(Data), 0) > 0); // SOCKET_ERROR = -1
end;

xxl1 20. Jun 2006 02:49

Re: Winsock , send/recv, wie?
 
ok danke für den tipp!
das mit der send() funktion scheint bei mir schon vorher nach ausprobieren geklappt zu haben. Leider werden die Daten scheinbar vom "Server" nicht empfangen.
Daher poste ich nun einmal den abstrahierten quellcode für den "server" in der reihenfolge wie ich die funktionen aufrufe:
Delphi-Quellcode:
function TNet.WinSock_startup;
  var wsa: TWSAData;
begin
  WSAStartup(MAKEWORD(2, 0), wsa);
end;
 
function TNet.Winsock_sockTCP;
begin
  S := socket (AF_INET , SOCK_STREAM , 0); // S : tSocket;
end;

function TNet.Winsock_setoptTCP;
begin
  s_addr.sin_family :=AF_INET;         // s_addr : sockaddr_in;
  s_addr.sin_port := htons(10000);
  s_addr.sin_addr.s_addr := htonl(INADDR_ANY);
  s_addr.sin_zero:='0';
end;

function TNet.WinSock_bindTCP;
begin
  bind ( S , s_addr , sizeof(s_addr));
end;

function TNet.Winsock_listenTCP;
begin
  listen(S , SOMAXCONN);
end;

function TNet.Winsock_acceptTCP;
begin
  S_accepting:= accept(S, nil, nil); // S_accepting : tSocket; {Socket der verbindungen akzeptiert durch accept() }
end;

function TNet.Winsock_reciveTCP;
begin
  result:=recv(S_accepting, buffer, strlen(buffer),0); // buffer : PChar;
end;
Dies sind also meine Funktionsaufrufe. Natürlich bleibt der "server" bei der funktion accept hängen solange keine verbindung duch den "client" mit connect() erstellt wurde. Danch führt der "client" die bereit erwähnte send() funktion durch und der "server" soll dies "nurnoch" mit dem der oben geposteten funtion recv() auslesen. Leider geschiet dies nicht.

Hoffe jemand erkennt die Fehler in meinem Quellcode und kann mir helfen.

Basilikum 20. Jun 2006 06:38

Re: Winsock , send/recv, wie?
 
Zitat:

Zitat von xxl1
Dies sind also meine Funktionsaufrufe. Natürlich bleibt der "server" bei der funktion accept hängen solange keine verbindung duch den "client" mit connect() erstellt wurde. Danch führt der "client" die bereit erwähnte send() funktion durch und der "server" soll dies "nurnoch" mit dem der oben geposteten funtion recv() auslesen. Leider geschiet dies nicht.

versuch es mal mit folgender Receive-Function:
Delphi-Quellcode:
function TNet.Winsock_reciveTCP;
Var
  Buffer : String;
  R : Integer;
begin
  SetLength(Buffer,1024);
  R:=recv(S_accepting, buffer[1], Length(buffer),0);
  If (R < 0) Then --fehler--

  SetLength(Buffer,R); // Empfangene Daten stehen nun im Buffer (String)
  OutputDebugString(PChar(Buffer)); // Sichtbar im Eventlog - Ctrl-Alt-V
end;

Nogge 20. Jun 2006 08:54

Re: Winsock , send/recv, wie?
 
accept reagiert auf
- Connecten eines neuen Clients
- Empfangen von Daten durch einen verbundenen Client (= Buffer hat neuen Inhalt)
d.h. wenn sich ein Client mit deinem Server verbunden hat, wurde der accept-Befehl einmal erfolgreich abgearbeitet. Somit musst du diesen in eine Schleife schreiben, damit nach dem Verbinden eines neuen Clients Daten von diesem empfangen werden können.

xxl1 20. Jun 2006 16:03

Re: Winsock , send/recv, wie?
 
Hi,

ERSTMAL ein dickes DANKE an Basilikum ,da ich jetzt schonmal strings übertragen kann!

Nogge , mir war klar das ich die accept() funktion in eine schleife einbauen muss ,aber es ging ja darum wie man send() ,recv() benutzt. Trotzdem danke.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 Uhr.
Seite 1 von 3  1 23      

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