Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi TSocks bind() Typen von Records stimmen nicht überein (https://www.delphipraxis.net/185029-tsocks-bind-typen-von-records-stimmen-nicht-ueberein.html)

SyntaxXx 9. Mai 2015 13:38

TSocks bind() Typen von Records stimmen nicht überein
 
Ich arbeite mich gerade in die Socketerstellung ein und stoße jetzt auf ein Problem.

Ich bekomme die Meldung: Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen

Nur verstehe ich diese Meldung nicht, bzw. verstehe nicht, warum diese kommt.
Aus der WinApi benutze ich das Record "SockAddr_in".

Delphi-Quellcode:
SocketAddress: SockAddr_in;

Dann fülle ich die Felder:
Delphi-Quellcode:
SocketAddress.sin_family := AF_INET;
SocketAddress.sin_port := htons(9000);
SocketAddress.sin_addr.S_addr := inet_addr(PAnsiChar('127.0.0.1'));

Dann möchte ich das Socket binden:
Delphi-Quellcode:
SocketError := bind(ListenSocket, SocketAddress, SizeOf(SockAddr_in));

Und genau an dieser Stelle kommt der Fehler.
"SocketAddress" wird markiert.


Warum kommt der Fehler und wie kann ich diesen Beheben?

Klaus01 9. Mai 2015 19:52

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Zitat:

Dann möchte ich das Socket binden:
SocketError := bind(ListenSocket, SocketAddress, SizeOf(SockAddr_in));
Und genau an dieser Stelle kommt der Fehler.
"SocketAddress" wird markiert.
Guten Abend,

so sollte es gehen:

Delphi-Quellcode:
SockAddrSize := sizeOf(SockAddr_in)
SocketError := bind(ListenSocket, SocketAddress, SocketAddrSize));
Grüße
Klaus

SyntaxXx 9. Mai 2015 20:59

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Hat leider auch nichts gebracht.
Hier mal der ganze Code, damit kann man bestimmt besser was mit anfangen :)

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, Winsock2, Windows;

var
  Data: WSAData;
  SocketError: Integer;
  ListenSocket: TSocket;
  ClientSocket: TSocket;
  SocketAddress: SockAddr_in;
  SocketAddressSize: Integer;
  MessageBytes: Integer;
  recvbuf: Array[0..511] of Char;

begin
  try
    { TODO -oUser -cConsole Main : Code hier einfügen }
    SocketError := WSAStartup(MAKEWORD(2,2), Data);

    if SocketError = 0 then
    begin
      ListenSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

      if NOT ListenSocket = INVALID_SOCKET then
      begin
        SocketAddress.sin_family := AF_INET;
        SocketAddress.sin_port := htons(9000);
        SocketAddress.sin_addr.S_addr := inet_addr(PAnsiChar('127.0.0.1'));

        SocketAddressSize := SizeOf(SockAddr_in);
        SocketError := bind(ListenSocket, SocketAddress, SocketAddressSize); // Hier der Fehler, auch nach der Änderung

        if SocketError = 0 then
        begin
          SocketError := listen(ListenSocket, SOMAXCONN);

          if SocketError = 0 then
          begin
            ClientSocket := accept(ListenSocket, Nil, Nil);

            if ClientSocket = TSocket then
            begin
              repeat
                MessageBytes := recv(ClientSocket, recvbuf, SizeOf(recvbuf), 0);
                Writeln(MessageBytes);
              until MessageBytes = 0 ;
            end;

          end;
        end;
      end;
    end;

    closesocket(ClientSocket);
    closesocket(ListenSocket);
    WSACleanup;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

himitsu 9. Mai 2015 22:31

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Zitat:

Aus der WinApi benutze ich das Record "SockAddr_in".
Was soll WinApi für eine Unit sein?

Wie wäre es, wenn du schaust, wo der Typ "SockAddr_in" deklariert ist,
dann schaust du wie "Bind" deklariert ist und von wo der Typ des Parameters kommt
und ob das wirklich der selbe Typ ist?

Klaus01 10. Mai 2015 08:59

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Zitat:

Delphi-Quellcode:
        SocketAddress.sin_family := AF_INET;
        SocketAddress.sin_port := htons(9000);
        SocketAddress.sin_addr.S_addr := inet_addr(PAnsiChar('127.0.0.1'));

in C auf Linux schaut das so aus:

Code:
listenSocket = socket(AF_INET, SOCK_STREAM,0);

socketAddress.sin_family = AF_INET
inet_pton(AF_INET,server_ip,&socketAddress.sin_addr.s_addr);
socketAddress.sin_port = htons(portNumber)
socketAddressSize = sizeOf(socketAddress)

Das Tutorial kennst Du schon?

bind(listenSocket, (stuct sockAddr_in*)&socketAddress, socketAddressSize)
Die Funktion bind() benötigt 3 Parameter.
Es beginnt mit der Identifiaktionsnummer (listenSocket) des Sockets,
der "gebunden"werde soll. Diese Nummer hatte zuvor aufgerufene socket()-Funktion erzeugt.
Dann kommt der Zeiger auf die Datenstruktur in der die Adressinformation gespeichert ist (socketAddress) und schließlich die Länge dieser Datenstruktur)
(Quelle: Martin Pollakowski, Grundkurs Socketprogrammierung mit C unter Linux)
Ähnlich sollte es auch mit Winsock funktionieren.

Das Tutorial kennnst Du schon?

Grüße
Klaus

SyntaxXx 10. Mai 2015 15:50

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Während ich gerade den Fehler weiter am beschreiben war, habe ich die Lösung gefunden.
Ich hatte die Unit "winsock2" eingebunden.
Die war sehr identisch mit der Unit "winsock", nur dass hier die bind-Methode das Record "sockaddr" benötigt und nicht "sockaddr_in".

Also habe ich die Unit "winsock" benutzt und schon gehts.


Und ich dachte:"Komm ich nehme winsock2, da das eine neurere Version der Unit ist".
Naja, falsch gedacht :)


Ich danke für eure Hilfe.

mjustin 11. Mai 2015 07:00

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Zitat:

Zitat von SyntaxXx (Beitrag 1300937)
Und ich dachte:"Komm ich nehme winsock2, da das eine neurere Version der Unit ist".

http://stackoverflow.com/questions/1...h-which-to-use

Zitat:

"winsock.h should only be used if you target old version of Windows like Windows 95 / Windows NT 3.5."
-> Winsock(.h) sollte nur verwendet werden wenn die Anwendung auf alten Versionen von Windows eingesetzt werden soll. Für neue Projekte sollte winsock2 verwendet werden.

SyntaxXx 11. Mai 2015 07:22

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Ähm ok, wenn ich aber jetzt winsock2 benutze, stehe ich vor dem Problem, dass die bind-Methode ein sockaddr-Record verlangt und kein sockaddr_in-Record.

Was also tun?

himitsu 11. Mai 2015 08:00

AW: TSocks bind() Typen von Records stimmen nicht überein
 
sockaddr verwenden? :stupid:

SyntaxXx 11. Mai 2015 08:09

AW: TSocks bind() Typen von Records stimmen nicht überein
 
Grundsätzlich keine schlechte Idee xD

Aber hier mal der Aufbau beider Strukturen:
Code:
struct sockaddr {
        ushort sa_family;
        char   sa_data[14];
};

struct sockaddr_in {
        short  sin_family;
        u_short sin_port;
        struct in_addr sin_addr;
        char   sin_zero[8];
};
Bei sockaddr fehlen mir jetzt leider "sin_port" und "sin_addr".


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:36 Uhr.
Seite 1 von 2  1 2      

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