Autor Beitrag
Peter18
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Mo 22.10.18 11:23 
Ein freundliches Hallo an alle,

mal wieder eine Pointerfrage. Oder ist es der Ansistring?

Ich habe mit Hilfe von Beispielen zum Teil in C eine Funktion geschrieben, die den Computernamen zurückgeben soll. Die stürzt aber hin und wieder ab. Ich habe bisher nicht herausfinden können, ob es ein Pointerproblem oder der Ansistring ist. Debuggen ist schwierig, da der Fehler nur gelegentlich auftritt. Ich hoffe jemand hat einen Tipp.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
function T_TcpServer.GetClientName( I : Integer; var E : String ): String;
var
  name      : TSockAddr;
  Host      : PHostEnt ;
  L         : Integer  ;

begin
  E      := ''            ;
  Result := ''            ;
  L      := SizeOf( name );
  E      := 'Conn'        ;
  if oSock[ I ].Conn then
  begin
    FillChar ( name, L, #0 )                                  ;
    name.sin_family := AF_INET                                ;
    name.sin_port   := oPortNr                                ;
    E               := 'getpeername'                          ;
    iRes            := getpeername( oSock[ I ].Sock, name, L );
    if iRes = 0 then
    begin
      try
        E      := 'gethostbyaddr';
        Host   := gethostbyaddr( @name.sin_addr, SizeOf( name.sin_addr ), AF_INET );
        E      := 'host^';
        Result := host^.h_name;
      except
      end;
    end;
    E := '';
  end;
end;

Die Variable E dient nur zum lokalisieren des Fehlers und zeigt "Result := host^.h_name;" als Ursache an.

Die Deklaration in der Winsock.pas:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  PHostEnt = ^THostEnt;
  {$EXTERNALSYM hostent}
  hostent = record
    h_name: PChar;
    h_aliases: ^PChar;
    h_addrtype: Smallint;
    h_length: Smallint;
    case Byte of
      0: (h_addr_list: ^PChar);
      1: (h_addr: ^PChar)
  end;
  THostEnt = hostent;


Grüße von der sonnigen Nordsee

Peter

Moderiert von user profile iconNarses: Titel korrigiert.
jasocul
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 6288
Erhaltene Danke: 120

Windows 7 + Windows 10
Tokyo Prof + CE
BeitragVerfasst: Mo 22.10.18 11:40 
Ändere deinen Except-Block mal so:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
  except
    on E:Exception do
      E := E.Message;
  end;

Dann sollte in E stehen, welchen Fehler du hast.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Mo 22.10.18 13:12 
Hallo jasocul,

dank Dir für die Anregung. Wenn man so etwas bei der Delphi 4 Hilfe sucht ist es ein Zufall, wenn man es findet. Irgendwann hatte ich so etwas schon mal gefunden, aber ich finde es nicht wieder.

Bin mal auf das Ergebnis gespannt, wie gesagt, das kann dauern.

Grüße von der immer noch sonnigen Nordsee

Peter
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2088
Erhaltene Danke: 381

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mo 22.10.18 17:16 
Guten Abend Peter18,

eine WinAPI Doku hat in der Delphi Hilfe nicht wirklich etwas verloren.
Entweder suchst du es direkt in der dafür vorgesehenen Doku, MSDN, oder du benutzt eine Suchmaschine deiner Wabl und lässt dich zum jeweiligen MSDN Eintrag weiterleiten.

Ich vermute, dass die Funktion getpeername() schon vorher fehlschlägt, denn sie benötigt als ersten Parameter eine Variabel vom Typ SOCKET bzw. TSocket, und das ist unter WinSock.pas als Integer festgelegt.
Bei dir ist stattdessen die Variable oSock gegeben, die wohlmöglich eine Struktur / record darstellt, dessen genauen Aufbau bzw. Typ ich nicht nachvollziehen kann.
Zitat:
Ich habe mit Hilfe von Beispielen zum Teil in C eine Funktion geschrieben, die den Computernamen zurückgeben soll

Dafür gibt es schon eine Funktion namens GetComputerName().

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1124
Erhaltene Danke: 73

Win7
DXE2 Prof, Lazarus
BeitragVerfasst: Di 23.10.18 08:21 
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
... Wenn man so etwas bei der Delphi 4 Hilfe sucht ist es ein Zufall ...

Delphi 4!
Embarcadero hat endlich etwas schon viele Jahre überfälliges getan und eine Community Version herausgebracht. Dies ist die neuste Version in vollem Umfang!
Soweit du nicht wegen alter Componenten (ohne source code), die du dringend brauchst, an der alten Version festhängst würde ich umsteigen. Dazwischen liegen Welten!
Die Version kann in beschränktem Umfang kommerziell verwendet werden.

Was du alleine von Delphi Seite an Funktionen dazu bekommst ist es Wert und du bekommst Programme die für die aktuellen Systeme erstellt worden sind und nicht für Windows 3.1!

_________________
Solange keine Zeile Code geschrieben ist, läuft ein Programm immer fehlerfrei.
Ich teste nicht, weil ich Angst habe Fehler zu finden.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Di 23.10.18 11:21 
Hallo Stefan,

Dank Dir für Deinen Hinweis. Hast Du einen Link? Bei Embarcadero habe ich nichts gefunden. Manches verstecken die gern.

Ich habe schon Berlin und Tokio ausprobiert, aber die laufen nicht unter XP. Win 10 macht mir noch zu viel Probleme. Plötzlich geht mein Grafiktablett nicht mehr, oder die Netzwerkanmeldung funktioniert nur nach Lust und Laune. (Nach der Neuinstallation [Platte kaput] war noch alles gut, aber dann kam ein Update.)

Grüße von der verregneten und stürmischen Nordsee

Peter
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1124
Erhaltene Danke: 73

Win7
DXE2 Prof, Lazarus
BeitragVerfasst: Di 23.10.18 12:57 
Die Community Version wird auf Win XP auch nicht laufen.
Du kannst es aber mal mit Lazarus (Free Pascal) probieren. Das sollte Dir vom Gefühl her auch mehr wie D4 vorkommen, dabei ist es modern und sehr flexibel.
Ich nutze es für Programme mit extremen Anforderungen an Speicher und CPU.

_________________
Solange keine Zeile Code geschrieben ist, läuft ein Programm immer fehlerfrei.
Ich teste nicht, weil ich Angst habe Fehler zu finden.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Di 23.10.18 14:57 
Hallo Stefan,

nochmals Dank. Es hat sehr viel Ähnlichkeit mit Delphi4, aber massenweise Objekte. Leider habe ich bei Delphi4 schon etliche Objekte an meinen Bedarf angepasst und um Eigenschaften und Methoden erweitert. Ich fürchte ich kann es nur als Referenz verwenden, wenn ich mein Projekt nicht komplett neu anfangen will. Vielleicht gibt es ja eine Funktion, die das gleiche tut wie "T_TcpServer.GetClientName".

Grüße von der sehr feuchten Nordsee

Peter
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Di 23.10.18 16:03 
Hallo Stefan,

Da steckt ja eine Menge drinn. Ich habe aber noch nichts gefunden um einen einfachen Server und Client für Tcp/IP zu bauen. Hast Du einen Tip, wo sich die Sachen verstecken, oder ein Beispiel?

Grüße von der noch immer verregneten und stürmischen Nordsee

Peter
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2088
Erhaltene Danke: 381

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Di 23.10.18 16:55 
Hm, statt auf den "Fehler" einzugehen, ist man nun der Auffassung, dass dieser durch eine modernere Entwicklungsumgebung zu umgehen ist?!
Sowas muss ich nicht verstehen.
Und auf die Frage, ob es eine ähnliche Funktion dazu gibt - Ja. Sie wurde verlinkt.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Sinspin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1124
Erhaltene Danke: 73

Win7
DXE2 Prof, Lazarus
BeitragVerfasst: Mi 24.10.18 11:34 
user profile iconPeter18 hat folgendes geschrieben Zum zitierten Posting springen:
Da steckt ja eine Menge drinn. Ich habe aber noch nichts gefunden um einen einfachen Server und Client für Tcp/IP zu bauen.

Freepascal hat eine gute Community und zahlreiche Samples zu den verschiedenen Komponenten. Ich habe bisher noch nix mit Netzwerkzugriff gemacht. Aber Synapse bietet Komponenten die viel referenziert werden wenn es um Netzwerkzugriff geht.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Hm, statt auf den "Fehler" einzugehen, ist man nun der Auffassung, dass dieser durch eine modernere Entwicklungsumgebung zu umgehen ist?!

Ich denke schon. Mit einer neueren Entwicklungsumgebung sind solche fehleranfälligen Konstrukte seltener nötig da dann genau die von Dir angesprochene Windowsfunktion schon fertig deklariert ist.
Ich glaube nicht das es die in D4 schon gibt.

_________________
Solange keine Zeile Code geschrieben ist, läuft ein Programm immer fehlerfrei.
Ich teste nicht, weil ich Angst habe Fehler zu finden.
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Mi 24.10.18 14:24 
Hallo Frühlingsrolle, hallo Stefan,

Dank Euch für Eure Antworten.

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Hm, statt auf den "Fehler" einzugehen, ist man nun der Auffassung, dass dieser durch eine modernere Entwicklungsumgebung zu umgehen ist?!
Sowas muss ich nicht verstehen.

Typischer Fall von Denkste! Stefan hat insovern recht, dass dort solche Fehler vermiden werden können, aber es kommt mir darauf an, dort den richtigen Weg zu den Schnittstellen zu finden und dann in meine Software zu übernehmen! Wie bereits bemerkt müßte ich alle geänderten Objekte prüfen, wenn ich auf einen anderen Compiler umsteige, aber abgucken ist hier erlaubt (um zu verstehen)!!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Und auf die Frage, ob es eine ähnliche Funktion dazu gibt - Ja. Sie wurde verlinkt.

????????????????????????????????????????????????????????????????????

Inzwischen stürzt das Programm anscheinend an anderer Stelle ab, aber ich forsche weiter!

Noch mal die Pointerfrage: "host^.h_name" steht in der Function, aber "host.h_name" liefert das selbe Ergebnis. Doch was ist richtig oder ist das egal??

PChar kann anscheinend ohne Probleme einem String zugewiesen werden.

Stefan Dank Dir für den Link, da habe ich viel zu lesen.

Grüße von der bewölkten Nordsee

Peter
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2088
Erhaltene Danke: 381

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Mi 24.10.18 17:36 
@ Sinspin

wenn die vordeklarierte WinAPI ein Problem darstellt, dann lässt man diese Unit gut sein und deklariert die Funktionen und Co. in einer eigenen Unit, so wie man es braucht.
Dazu braucht man nicht mehr als MSDN, wo eh alles nennenswerte drin steht.
Neues Delphi, hin oder her ist Quatsch.

@ Peter18

Im ersten Beitrag von mir nachLESEN
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Fr 26.10.18 14:50 
Hallo Frühlingsrolle,

nochmals Dank für Deine Antwort, aber
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Neues Delphi, hin oder her ist Quatsch.
ist leider Falsch!

Da meine Delphi-Version viele Schnittstellen nicht enhält wie z.B. TAPI, MAPI und auch TCP/IP, muß ich die Deklarationen selbst erstellen! Da kann eine neue Version, die diese Deklarationen enthält, schon sehr hilfreich sein. Damit gibt es auch keine vordefinierten Schnittstellen, die ich nutzen könnte!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
denn sie benötigt als ersten Parameter eine Variabel vom Typ SOCKET bzw. TSocket
ist mit "name : TSockAddr;" deklariert.
user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Dafür gibt es schon eine Funktion namens GetComputerName().
Die liefert
Zitat:
Retrieves the NetBIOS name of the local computer. This name is established at system startup, when the system reads it from the registry.
also den Namen des Rechners auf dem das Programm läuft und nicht den Namen des Rechners im Netz, der sich mit "T_TcpServer" verbinden will!

Da aber nun der Fehler öfter auftritt kann ich nun meine Frage selbst beantworten:
"host^.h_name" und "host.h_name" liefern beide das gleiche Ergebnis! Demnach ist die Dereferenzierung nicht unbedingt nötig.

"getpeername" liefert bei manchen Sockets den Wert 0 zurück, "gethostbyaddr" aber NIL. Warum konnte ich noch nicht feststellen, da das nicht regelmäßig geschieht. Daher ist
ausblenden Delphi-Quelltext
1:
if Assigned( host ) then Result := host^.h_name;					

angebracht.

Grüße von der verregneten Nordsee

Peter
Frühlingsrolle
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2088
Erhaltene Danke: 381

[Win NT] 5.1 x86 6.1 x64
[Delphi] 7 PE, 2006, 10.1 Starter, Lazarus - [C#] VS Exp 2012 - [Android API 15] VS Com 2015, Eclipse, AIDE - [C++] Builder 10.1
BeitragVerfasst: Fr 26.10.18 18:06 
user profile iconPeter18 hat folgendes geschrieben:
Da meine Delphi-Version viele Schnittstellen nicht enhält wie z.B. TAPI, MAPI und auch TCP/IP, muß ich die Deklarationen selbst erstellen!

Die Frage ist überhaupt, ob du das alles wirklich brauchst?
Eine Socket-Unterhaltung zwischen Server und Client bekommst du mit Winsock ebenso hin, das du hier zum Teil sowieso verwendest, siehe:
- sockaddr (TSockAddr)
- hostent (P/THostEnt)
- getpeername
- gethostbyaddr

Um eine Verbindung aufzubauen, zu trennen sowieo Verbindungsfehler festzustellen, benötigst du nicht mehr als:
- WSADATA
- WSAStartup
- WSACleanup
- WSAGetLastError
und eine Auflistung von sämtlichen Fehlerwerten: Windows Sockets Error Codes

Wenn du all das in eine Unit zusammenfasst, kann es dir egal sein, welche Delphi oder Freepascal Version verwendet wird.

Ein Anwendungsbeispiel zu Server und Client siehe: Running the Winsock Client and Server Code Sample
Sowie für eine sichere Übertragung: Using Secure Socket Extensions

user profile iconPeter18 hat folgendes geschrieben:
user profile iconFrühlingsrolle hat folgendes geschrieben:
denn sie benötigt als ersten Parameter eine Variabel vom Typ SOCKET bzw. TSocket

ist mit "name : TSockAddr;" deklariert.

Nach "name" wurde nicht gefragt:
user profile iconFrühlingsrolle hat folgendes geschrieben:
Ich vermute, dass die Funktion getpeername() schon vorher fehlschlägt, denn sie benötigt als ersten Parameter eine Variabel vom Typ SOCKET bzw. TSocket, und das ist unter WinSock.pas als Integer festgelegt.
Bei dir ist stattdessen die Variable oSock gegeben, die wohlmöglich eine Struktur / record darstellt, dessen genauen Aufbau bzw. Typ ich nicht nachvollziehen kann.

user profile iconPeter18 hat folgendes geschrieben:
"getpeername" liefert bei manchen Sockets den Wert 0 zurück, "gethostbyaddr" aber NIL. Warum konnte ich noch nicht feststellen

Wenn getpeername() den Wert 0 liefert, dann war der Aufruf erfolgreich.
Wenn gethostbyaddr() den Wert nil liefert, dann war der Aufruf NICHT erfolgreich.
Das steht alles in den verlinkten Beiträgen.

_________________
„Politicians are put there to give you the idea that you have freedom of choice. You don’t. You have no choice. You have owners. They own you. They own everything." (George Denis Patrick Carlin)
Peter18 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 463
Erhaltene Danke: 2


Delphi4
BeitragVerfasst: Sa 27.10.18 10:30 
Hallo Frühlingsrolle,

ich weiß nicht, was Du hier mit mir diskutieren willst!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Die Frage ist überhaupt, ob du das alles wirklich brauchst?

Wieso diese Frage????? Wenn ich mich damit beschäftige werde ich sie wohl brauchen und sei es auch nur um zu lernen!!

Du wirst vielleicht erstaunt sein, aber nach "Running the Winsock Client and Server Code Sample" habe ich meine "T_TCPIP" entwickelt und dazu die "winsock.pas" studiert. Aber dennoch brauchte ich eine "winsock2.pas". Ich will aber nicht diesen Teil meiner Software diskutieren, ohne weitere Deteils zu diesem Thema ist das fruchtlos! Ich hatte einen seltenen Absturz und deshalb gefragt, ob die Zuweisung von PChar zu String und der Pointer korrekt ist!

user profile iconFrühlingsrolle hat folgendes geschrieben Zum zitierten Posting springen:
Wenn getpeername() den Wert 0 liefert, dann war der Aufruf erfolgreich.
Wenn gethostbyaddr() den Wert nil liefert, dann war der Aufruf NICHT erfolgreich.

Welch Abgrund an Weisheit! Ich war davon ausgegangen, dass ein fehlerfreier Aufruf von "getpeername" auch einen gültigen Pointer bei "gethostbyaddr" zur Folge hat, was ich aber jetzt revidieren konnte!

Sicher sind noch weitere Fehler in meiner Software, aber Fehler sind dazu da, um aus ihnen zu lernen. Im Moment scheint sich ein Fehler in der Tapi abzuzeichnen, aber den muß ich erst noch einkreisen.

Für den Link "Windows Sockets Error Codes" meinen Dank, ich weiß nicht, ob ich den schon in meiner Linksammlung habe. Wenn nicht werde ich ihn hinzufügen.

Grüße von der sonnigen Nordsee

Peter