Autor |
Beitrag |
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Di 31.03.15 16:09
Ein freundliches Hallo an alle,
ich weiß, diese Frage habe ich bereits in einem anderen Thread gestellt, aber dort ist sie vielleicht etwas untergegangen. Daher stelle ich sie in einem neuen noch mal und hoffe auf einen Tipp.
In meiner Delphi 4 Version sind keine Objekte für Netzwerkanwendungen enthalten, aber die "winsock.pas". Ich brauche auch keine vollständige Netzwerk-Software. Ich möchte nur ein paar Informationen über Netzwerk mit einem anderen Rechner austauschen. Bei MS habe ich das Beispiel für einen Server gefunden und mit Delphi 4 programmiert (quick and dirty). Es geht auch alles gut bis " accept". Hier läuft er in die Wüste oder in einer Endlosschleife. Vielleicht ein falsch übergebener Parameter? Beim Aufruf von " CSock := accept( SSock, Nil, Nil );" kehrt die Kontrolle nicht zurück. Eine Absturzmeldung gibt es nicht.
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: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86:
| procedure TForm1.Button1Click(Sender: TObject); var VerR : word; WSADATA : TWSAData; Res : Integer; hints : PAddrInfo; ARes : PAddrInfo;
begin VerR := 2; Res := WSAStartup( VerR, WSADATA ); if Res = 0 then begin hints := AllocMem( SizeOf( TAddrInfo ) ); ARes := AllocMem( SizeOf( TAddrInfo ) ); hints.ai_flags := 0; hints.ai_family := AF_INET; hints.ai_socktype := SOCK_STREAM; hints.ai_protocol := IPPROTO_TCP; hints.ai_flags := AI_PASSIVE;
Res := getaddrinfo(Nil, PChar( Edit2.Text ), hints, ARes ); if Res = 0 then begin SSock := socket( ARes.ai_family, ARes.ai_socktype, ARes.ai_protocol ); if SSock <> INVALID_SOCKET then begin Res := bind( SSock, ARes.ai_addr^, ARes.ai_addrlen ); if Res <> SOCKET_ERROR then begin freeaddrinfo( ARes ); Res := listen( SSock, SOMAXCONN ); if Res = 0 then begin CSock := accept( SSock, Nil, Nil ); if CSock <> INVALID_SOCKET then begin closesocket( SSock ); end else begin Memo1.Lines.Add( 'Fehler Erstellen des Clientports: ' + IntToStr( WSAGetLastError ) ); closesocket( SSock ); WSACleanup; end; end else begin Memo1.Lines.Add( 'Fehler Portprüfung: ' + IntToStr( WSAGetLastError ) ); closesocket( SSock ); WSACleanup; end; end else begin Memo1.Lines.Add( 'Fehler beim Binden: ' + IntToStr( WSAGetLastError ) ); freeaddrinfo( ARes ); closesocket( SSock ); WSACleanup; end; end else begin Memo1.Lines.Add( 'Fehler beim Erstellen des Socket : ' + IntToStr( WSAGetLastError ) ); freeaddrinfo( ARes ); WSACleanup; end; end else begin Memo1.Lines.Add( 'Fehler bei der Portprüfung: ' + IntToStr( Res ) ); WSACleanup; end; end else begin Memo1.Lines.Add( 'Initialisierungsfehler: ' + IntToStr( Res ) ); end; end; |
Ich habe irgentwie die Zeile " Res := bind( SSock, ARes.ai_addr^, ARes.ai_addrlen );" in verdacht.
Ich hoffe jemand hat einen Tipp.
Grüße von der sonnigen Nordsee
Peter
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 31.03.15 16:50
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Di 31.03.15 17:22
Hallo Perlsau,
selten so gelacht!!!
Perlsau hat folgendes geschrieben : | Das kannst du doch einfach herausfinden, indem du durch diese Methode stepst – das nennt man Debuggen |
Es handelt sich nicht um eine Methode! Es ist eine Schnittstellenroutine der Winsock! Zwar kann ich in die CPU-Ansicht gehen, aber irgendwo geht es einfach nicht mehr weiter. Die Ursache ist nicht erkennbar.
Vielleicht hat aber jemand entsprechende Methoden (Objekte) und kann, per debug, nachsehen ob die Parameter rictig aufgesetzt sind, oder ob da noch etwas fehlt.
Grüße von der windigen Nordsee
Peter
Moderiert von Narses: Komplettzitat des ersten Beitrags entfernt.
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Di 31.03.15 17:34
Peter18 hat folgendes geschrieben : | Beim Aufruf von "CSock := accept( SSock, Nil, Nil );" kehrt die Kontrolle nicht zurück. Eine Absturzmeldung gibt es nicht. |
Schau Dir mal an was MS zu Accept schreibt, das ist das ganz normale Verhalten dieser Funktion.
Es wird solange gewartet bis ein Clientsocket daherkommt und mit dem Server eine Verbindung eingeht. Dann geht es in deinem Programmablauf weiter.
Das ist einer der Gründe warum man den Server in einen eigenen Thread packt anstatt ihn ihm Hauptthread auszuführen.
Dein Beispiel eigenet sich aber schön zum testen. Du brauchst jetzt nur ein zweites Programm (das mit dem Server ist ja blockiert) das den Client implementiert und via ButtonClick siehst Du dann wie der Server weitermacht wenn der Client sich verbindet.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 31.03.15 18:21
Peter18 hat folgendes geschrieben : | Hallo Perlsau, selten so gelacht!!! |
Warum klingst du dann so verägert, da du doch angeblich lachst?
Peter18 hat folgendes geschrieben : | Perlsau hat folgendes geschrieben : | Das kannst du doch einfach herausfinden, indem du durch diese Methode stepst – das nennt man Debuggen |
Es handelt sich nicht um eine Methode! Es ist eine Schnittstellenroutine der Winsock! Zwar kann ich in die CPU-Ansicht gehen, aber irgendwo geht es einfach nicht mehr weiter. Die Ursache ist nicht erkennbar. |
Du hattest aber doch geschrieben:
Peter18 hat folgendes geschrieben : | ... Ich habe irgentwie die Zeile "Res := bind( SSock, ARes.ai_addr^, ARes.ai_addrlen );" in verdacht. |
Um den Verdacht zu bestätigen, stepst du dein Programm so lange durch, bis der Fehler auftritt. Tritt er an der von dir bezeichneten Stelle auf, dann wird der bloße Verdacht zur Gewißheit.
Tatsächlich befindet sich diese Zeile, die du unter Verdacht gestellt hattest, in einer Methode deines Form1-Objekts. Was gibt's da also zu meckern? Wenn du etwas anderes gemeint als geschrieben hast, darfst du nicht mich dafür verantwortlich machen
Zuletzt bearbeitet von Perlsau am Di 31.03.15 18:23, insgesamt 1-mal bearbeitet
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Mi 01.04.15 11:59
Hallo Sinspin,
vielen Dank für Deine Antwort! Ich habe so etwas schon vermutet, aber leider bei MS nicht gefunden. Die Beschreibung ist sehr kurz: "The accept function permits an incoming connection attempt on a socket." Falls Du eine genauere Beschreibung kennst, wäre ich für einen Link sehr dankbar. Vielleicht sind dort auch Infos zu anderen Routinen zu finden. Das Ganze soll später auch in einem Thread laufen und dient zunächst dazu, um den Einstieg zu finden.
Ich hatte den Server auf einem anderen Rechner im Netzwerk laufen, doch konnte keine Reaktion feststellen, als ich einen Client darauf losgelassen habe. Vielleicht ist da noch ein Fehler drin. Nochmals Dank, Du hast meine Vermutung bestätigt.
Hallo Perlsau,
Du wunderst Dich dass ich etwas vergrätzt bin?
Perlsau hat folgendes geschrieben : | – das nennt man Debuggen |
Wieso habe ich das Gefühl für dumm verkauft zu werden???
Leider habe ich ab und zu den Eindruck das einige wenige glauben andere von oben herab behandeln zu können oder Fragen nicht richtg lesen. Nicht nur in diesem Forum, in anderen sogar häufiger. Wer hier eine Frage stellt, dem sollte man unterstellen, dass er ein Problem hat. Natürlich gibt es auch Ausnahmen. Manchmal hat man sich so festgebissen, dass man den Wald vor lauter Bäumen nicht sieht. Nicht selten habe ich mich im Forum angemeldet, um eine Frage zu stellen und beim Formulieren der Frage fand ich selbst die Lösung. Leider klappt das nicht immer! Auch bei der Suche nach Informationen dreht man sich gern mal im Kreis und landet immer wider bei den selben Informationen.
Natürlich kommt es vor, dass ein "Unwissender" seine Frage so formuliert, dass ein "Wissender" nicht erkennt wo das Problem liegt. Dann müssen die Mißverständnisse im Dialog ausgeräumt werden, aber bitte auf Augenhöhe! Der "Unwissende" lernt auch daraus!
Aber zurück zu Deiner Antwort:
Perlsau hat folgendes geschrieben : | Tatsächlich befindet sich diese Zeile, die du unter Verdacht gestellt hattest, in einer Methode deines Form1-Objekts. |
Selbstverständlich befindet sich der Aufruf dieser Funktion dort, aber sie ist Teil der Winsock! Dort kann ich nur auf Assemblerebene debuggen! Da ich schon mehrfach versucht habe auf dieser Ebene meine Parameter zu finden, aber keine schlüssigen Erkenntnisse gewinnen konnte, wie Delphi sie weitergibt, war ich mir nicht sicher, ob sie korrekt übergeben werden.
Vielleicht solltest Du auch mal über Deinen Fußtext nachdenken, wenn Du einen anderen Eindruck vermitteln möchtest.
Grüße von der noch immer windigen Nordsee
Peter
Für diesen Beitrag haben gedankt: Tastaro
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 01.04.15 13:36
Peter18 hat folgendes geschrieben : | Du wunderst Dich dass ich etwas vergrätzt bin? |
In der Tat! Etwas? Mir scheint, gewaltig. Kapier ich nicht wirklich. Wenn ich zu dumm bin, deinen Text zu verstehen, wieso ärgert dich das?
Peter18 hat folgendes geschrieben : | Vielleicht solltest Du auch mal über Deinen Fußtext nachdenken, wenn Du einen anderen Eindruck vermitteln möchtest. |
Mein Fußtext? Ich hab keinen Text auf meinem Fuß! Du meinst sicher meine Signatur. Hat die dich etwa vergrätzt? Aber stimmt, du hast recht, ich geb's ja ganz offen zu: Diese Signatur hab ich nur wegen dir, weil ich genau weiß, daß du dich darüber ärgerst. Ich bin halt ein schlimmer Finger, schlechte Gene, minderwertiger Abschaum eben, zu dumm zum Verstehen einfachster Texte (ist zum Glück alles noch nicht verboten). Hab ich kein Problem damit; es gibt zum Ausgleich ja auch wertvoll-intelligente Menschen wie dich, nicht wahr? Stell dir nur vor, alle wären so wertvoll wie du, würdest du dich da noch als was Besonderes fühlen können? Es muß auch Dumpfbacken wie mich geben, um den notwendigen Kontrast zu ermöglichen.
Nochmal: Du hattest von einem Verdacht geschrieben und eine Zeile benannt. Ein Verdacht ist keine Gewißheit. Um Gewißheit zu erlangen, benutzt man den Debugger. Was ist daran falsch? Daß du dir in Wirklichkeit sicher warst, daß der Aufruf in dieser Zeile das Problem darstellt? Geschrieben hast du aber was anderes. Und nun darfst du dich gerne weiterärgern, wenn du meinst, daß dir das was bringt. Mir ist es wurscht.
Aber lassen wir das, du hast da was in den falschen Hals gekriegt und machst mich dafür verantwortlich. Keine Ahnung, welchen Eindruck du damit machen wolltest ...
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Mi 01.04.15 13:48
Ein freundliches Hallo an alle,
hier ein Update: Der Client läuft bis "Res := connect( CSock, ARes.ai_addr^, ARes.ai_addrlen );" und gibt -1 zurück. In Edit1.Text steht der jeweilige Servername, in Edit2.Text die Portnummer "27015". Nachdem ich den Server gestartet habe wird der Client auf einem anderen gestartet.
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: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60:
| procedure TForm1.Button1Click(Sender: TObject); var VerR : word; WSADATA : TWSAData; Res : Integer; hints : PAddrInfo; ARes : PAddrInfo;
begin VerR := 2; Res := WSAStartup( VerR, WSADATA ); if Res = 0 then begin hints := AllocMem( SizeOf( TAddrInfo ) ); hints.ai_flags := 0; hints.ai_family := AF_UNSPEC; hints.ai_socktype := SOCK_STREAM; hints.ai_protocol := IPPROTO_TCP;
Res := getaddrinfo( PChar( Edit1.Text ), PChar( Edit2.Text ), hints, ARes ); if Res = 0 then begin Memo1.Lines.Add( 'socket' ); CSock := socket( ARes.ai_family, ARes.ai_socktype, ARes.ai_protocol ); if CSock <> INVALID_SOCKET then begin Memo1.Lines.Add( 'connect' ); Res := connect( CSock, ARes.ai_addr^, ARes.ai_addrlen ); Memo1.Lines.Add( 'connect: ' + IntToStr( Res ) ); if Res <> SOCKET_ERROR then begin Connected := true; freeaddrinfo( ARes ); end else begin Memo1.Lines.Add( 'Fehler bei connect: ' + IntToStr( Res ) ); closesocket( CSock ); freeaddrinfo( ARes ); end; end else begin Memo1.Lines.Add( 'Fehler bei socket: ' + IntToStr( WSAGetLastError ) ); freeaddrinfo( ARes ); WSACleanup; end; if CSock = INVALID_SOCKET then WSACleanup; end; FreeMem( hints ); end else begin Memo1.Lines.Add( 'Fehler bei WSAStartup: ' + IntToStr( Res ) ); WSACleanup; end; end; |
Ich hoffe auf einen Tipp.
Grüße von der Nordsee
Peter
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Mi 01.04.15 13:50
Hallo Perlsau,
siehe oben, Antwort überflüssig!
|
|
Tastaro
Beiträge: 414
Erhaltene Danke: 23
|
Verfasst: Mi 01.04.15 14:07
Ermittelt getaddrinfo die richtige IP-Adresse?
Firewall auf dem Rechner mit dem Server?
Bei mir sieht die connect-Routine so aus:
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: 32: 33: 34: 35: 36: 37: 38: 39: 40:
| function to_tcpip_client_socket.connect(strIp: string; iPort: integer): integer; var recSocketAddress: tsockaddrin; pcIp: pchar; begin disconnect;
recSocketAddress.sin_family := PF_INET; recSocketAddress.sin_port := htons(iPort); pcIp := pchar(strIp); recSocketAddress.sin_addr.S_addr := inet_addr(pcIp);
iSocketHandle := winsock.socket(AF_INET, SOCK_STREAM, 0);
if (iSocketHandle <> INVALID_SOCKET) then begin if winsock.connect(iSocketHandle, recSocketAddress, sizeof(recSocketAddress)) = 0 then Result := 0 else begin Result := winsock.wsagetlasterror; winsock.closesocket(iSocketHandle); iSocketHandle := INVALID_SOCKET; end; end else Result := winsock.wsagetlasterror; boConnected := (Result = 0); if boConnected then begin strRemoteIp := strIp; iRemotePort := iPort; oClientThread := to_tcpip_client_thread.create(iSocketHandle, iReceiveBufferSize_bytes); oClientThread.yOnDisconnect := on_disconnect; oClientThread.yOnError := on_error; oClientThread.yOnDataReceived := on_data_received; oClientThread.resume; end; end; |
|
|
Sinspin
Beiträge: 1332
Erhaltene Danke: 118
Win 10
RIO, CE, Lazarus
|
Verfasst: Mi 01.04.15 14:27
Hallo Peter,
Microsoft ist in Sachen API Dokumentation wirklich brauchbar. Das einzige was man machen muss, ist sich durch alle verwendeten Befehle zu graben und auch den angegebenen Links mal zu folgen. In deinem Fall bin ich nicht bei Accept fündig geworden, sondern bei Listen. Gesucht habe ich via goggel nach "MSDN socket accept", dann ist es gleich der erste Treffer.
Edith:
Starte mal Server und Client auf dem gleichen Rechner. So kannst du erstmal noch ein paar Fehlerquellen ausschließen.
Peter, sei so nett und ignorier einfach die kindischen Spielchen, ich bin mir sicher Du stehst da deutlich drüber. Unsere perl sau ist halt noch jung und sucht immer mal nach Gelegenheiten mit älteren seine Kräfte zu messen.
_________________ Wir zerstören die Natur und Wälder der Erde. Wir töten wilde Tiere für Trophäen. Wir produzieren Lebewesen als Massenware um sie nach wenigen Monaten zu töten. Warum sollte unser aller Mutter, die Natur, nicht die gleichen Rechte haben?
Für diesen Beitrag haben gedankt: Peter18
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Mi 01.04.15 14:36
Hallo Tastaro,
Dank für Deine Antwort. Inzwischen bin auch ich auf die Brandmauer gekommen und siehe da, Ausname eintragen und es klappt! Die Funktionen "htons" und "inet_addr" habe ich nicht verwendet, weil sie im Beispiel von MS nicht vorgegeben waren. Die Namensauflösung soll laut Beschreibung in "getaddrinfo" erfolgen. Da sie in der "winsock.pas" meiner Version nicht enthalten war, habe ich sie entsprechend deklariert. Ein Objekt "Winsock" muß ich mir erst noch stricken.
Werd mir Deine Lösung aber noch genauer ansehen. Danke!
Grüße von der momentan sonnigen aber noch sehr windigen Nordsee
Peter
|
|
Peter18
Beiträge: 489
Erhaltene Danke: 2
Delphi4
|
Verfasst: Mi 01.04.15 14:52
Hallo Stefan,
Danke für Deine Antwort, auch für die "perl sau". Schade nur, dass er nicht lesen kann.
Der Tipp mit "Listen" scheint gut zu sein. Unter "Remarks" steht einiges an Text.
Ich hatte auch überlegt, ob ich auf einem Rechner testen sollte, war mir aber nicht sicher, ob ich ohne zusätzliche Funktionsaufrufe einen Port mehrfach benutzen kann.
Grüße von der Nordsee
Peter
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mi 01.04.15 15:20
Da haben sich nun also zwei zusammengetan zum gemeinsamen Provozieren. Sehr unreifes Verhalten, finde ich. Möchtet ihr euch gerne dem Admin erklären oder hört das jetzt auf?
|
|
|