AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Winsock , send/recv, wie?
Thema durchsuchen
Ansicht
Themen-Optionen

Winsock , send/recv, wie?

Ein Thema von xxl1 · begonnen am 19. Jun 2006 · letzter Beitrag vom 20. Apr 2007
Antwort Antwort
Seite 1 von 3  1 23      
xxl1

Registriert seit: 21. Apr 2006
88 Beiträge
 
FreePascal / Lazarus
 
#1

Winsock , send/recv, wie?

  Alt 19. Jun 2006, 00:26
Hallo mitnander!
Ich möchte eine schlanken server und client programmieren die daten austauschen.
Kommuniziert wird über TCP also:
 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!
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#2

Re: Winsock , send/recv, wie?

  Alt 19. Jun 2006, 07:17
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...
  Mit Zitat antworten Zitat
xxl1

Registriert seit: 21. Apr 2006
88 Beiträge
 
FreePascal / Lazarus
 
#3

Re: Winsock , send/recv, wie?

  Alt 19. Jun 2006, 18:11
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?
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#4

Re: Winsock , send/recv, wie?

  Alt 19. Jun 2006, 18:55
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...
  Mit Zitat antworten Zitat
xxl1

Registriert seit: 21. Apr 2006
88 Beiträge
 
FreePascal / Lazarus
 
#5

Re: Winsock , send/recv, wie?

  Alt 19. Jun 2006, 23:28
ok danke für die Info ,hat leider nicht zum gewünschtrn Effekt geführt.
  Mit Zitat antworten Zitat
Nogge

Registriert seit: 15. Jul 2004
336 Beiträge
 
Delphi 7 Professional
 
#6

Re: Winsock , send/recv, wie?

  Alt 20. Jun 2006, 01:46
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;
  Mit Zitat antworten Zitat
xxl1

Registriert seit: 21. Apr 2006
88 Beiträge
 
FreePascal / Lazarus
 
#7

Re: Winsock , send/recv, wie?

  Alt 20. Jun 2006, 03:49
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.
  Mit Zitat antworten Zitat
Basilikum

Registriert seit: 9. Aug 2003
389 Beiträge
 
Delphi 7 Professional
 
#8

Re: Winsock , send/recv, wie?

  Alt 20. Jun 2006, 07:38
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;
  Mit Zitat antworten Zitat
Nogge

Registriert seit: 15. Jul 2004
336 Beiträge
 
Delphi 7 Professional
 
#9

Re: Winsock , send/recv, wie?

  Alt 20. Jun 2006, 09:54
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.
  Mit Zitat antworten Zitat
xxl1

Registriert seit: 21. Apr 2006
88 Beiträge
 
FreePascal / Lazarus
 
#10

Re: Winsock , send/recv, wie?

  Alt 20. Jun 2006, 17:03
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 10:43 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