![]() |
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:
Es funktioniert alles bis auf die send/recv finktionen. Die Verbindung zwischen client und server steht(State= established),
S := socket (AF_INET, SOCK_STREAM , 0);
dann will ich vom client zum server etwas senden:
Delphi-Quellcode:
hier gibt mir WSAGetLastError 5 aus.
function TNet_client.Winsock_sendTCP;
var bytecount:integer; begin buffer:='Ein wichtiges Datenpaket'; bytecount:=send(S, buffer, strlen(buffer), 0);
Delphi-Quellcode:
hier wird mir für datacount -1 ausgegeben (Socket error)
function TNet.Winsock_reciveTCP;
var datacount: integer; begin datacount:=recv(S, buffer, sizeof(buffer),0); end; und natürlich ist der buffer leer. Weiss jemand wieso? Wenn ja, dann postet mal fleißig! Danke schonmal! |
Re: Winsock , send/recv, wie?
ich nehme an, buffer ist bei dir PChar !?
Code:
(send() erwartet keinen Pointer, sondern eine untypiserte Variable)
function TNet_client.Winsock_sendTCP;
var bytecount:integer; begin buffer:='Ein wichtiges Datenpaket'; bytecount:=send(S, buffer[color=#ff001f]^[/color], strlen(buffer), 0); zum 2. Problem: verrate uns doch noch, von welchem Type buffer ist... aller Pointer-ähnlichen Dinge scheiden aus, da du sizeof() verwendest... |
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? |
Re: Winsock , send/recv, wie?
Zitat:
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... |
Re: Winsock , send/recv, wie?
ok danke für die Info ,hat leider nicht zum gewünschtrn Effekt geführt.
|
Re: Winsock , send/recv, wie?
Hallo xxl1,
Du musst nach dem Erstellen des Sockets natürlich erst mal zum Server connecten:
Delphi-Quellcode:
Falls du das bereits getan hast, solltest du mithilfe der folgenden Funktion einen string übermitteln können:
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;
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; |
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:
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.
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; Hoffe jemand erkennt die Fehler in meinem Quellcode und kann mir helfen. |
Re: Winsock , send/recv, wie?
Zitat:
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; |
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. |
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 02:47 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 by Thomas Breitkreuz