boost.asio - Es konnte keine Verbindung hergestellt werden..
-
Kannst Du mal den relevanten Client-Code posten, bitte?
-
Also für den Client benutze ich ziemlich genau das von hier:
http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/tutorial/tutdaytime1.htmlBis zu dem for( ;; ) ist es sogar genau das gleiche. Und da scheint irgendwie das Problem zu sein.
Sprich
socket.connectkommt zurück, ohne das beim Serveracceptor.acceptanschlägt.
Ich dachte halt, dass der Socket da warten muss, bis er beim Server accepted ist, aber das scheint iwie nicht notwendig zu sein..btw:
Ich habe mir nochmal ein wenig Gedanken gemacht und ich finde, dass ich das gar nicht asynchron machen muss.. Macht imo keinen Sinn. Der Server wartet ja in einem eigenen Thread auf neue Clients und die Clients müssen warten bist überhaupt mal einen Verbindung zustande kommt, damit sie etwas weiter tun können. (Sprich Befehle vom Server erhalten)./EDIT:
Achso, nein, sorry. Ich habe ein anderes Query:tcp::resolver::query query ( server.c_str (), port );Da wird eine IP und ein Port angegeben. (Also lokale IP und Port 13)
Hmm. Vlt. liegts am Port 13, dass er doch was findet.. Gleich mal testen./EDIT:
Nein. Liegt anscheinend auch nicht am Port. Habe ein paar nicht zugewiesene Ports versucht, aber die geben wieder das gleiche Bild..
-
Du hast da einen Mutex. Kann es sein, dass noch irgendetwas anderes das Ding lockt?
-
Tachyon schrieb:
Du hast da einen Mutex. Kann es sein, dass noch irgendetwas anderes das Ding lockt?
Ja, aber nicht zu dem Zeitpunkt.
-
Sicher? Bei mir funktioniert der Code (oder das, was ich mit den gegeneben Informationen nachbasteln kann):
Server:
#include <iostream> #include <boost/asio/io_service.hpp> #include <boost/asio/ip/tcp.hpp> #include <boost/thread.hpp> #include <boost/ptr_container/ptr_list.hpp> using namespace boost::asio; using namespace boost::asio::ip; boost::asio::io_service server_io_service; boost::ptr_list< tcp::socket > connections; boost::mutex m; void accepting () { for (;;) { tcp::acceptor acceptor (server_io_service, tcp::endpoint (tcp::v4(), 13) ); tcp::socket* socket = new tcp::socket ( server_io_service ); acceptor.accept ( *socket ); { boost::lock_guard<boost::mutex> lock ( m ); connections.push_back ( socket ); std::cout << "Accepted...\n"; } } } int main() { boost::thread t(&accepting); t.join(); }Client:
#include <iostream> #include <boost/array.hpp> #include <boost/asio/io_service.hpp> #include <boost/asio/ip/tcp.hpp> using boost::asio::ip::tcp; int main(int argc, char* argv[]) { try { if (argc != 2) { std::cerr << "Usage: client <host>" << std::endl; return 1; } boost::asio::io_service io_service; tcp::resolver resolver(io_service); tcp::resolver::query query(argv[1], "13"); tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); tcp::resolver::iterator end; tcp::socket socket(io_service); boost::system::error_code error = boost::asio::error::host_not_found; while (error && endpoint_iterator != end) { socket.close(); socket.connect(*endpoint_iterator++, error); } if (error) throw boost::system::system_error(error); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } }Mit dem oben stehenden Code kann ich Client starten so oft ich will. Die Verbindungen werden immer angenommen.
Das einzige potentielle Hemmnis das mir auffällt ist der Mutex.
-
OK, Danke, werde da Morgen mal einen genauen Abgleich machen, was anderst läuft.. Sieht auf den ersten Moment ziemlich genau gleich aus, wie bei mir, aber mal schauen, wo die Kleinigkeit zu finden ist.

-
Hmm. Ich habs nochmal ausprobiert.
Jetzt war es so, dass ich den acceptor mittlerweilen aus der Funktion gezogen habe und ihn global gemacht habe, damit ich (z.B bei dir in der main vom Server) darauf zugreifen kann).
Wenn ich den acceptor wieder in die Funktion nehme (wie bei dir wieder) scheint es zu gehen, aber ich habe jetzt dafür bei einem Client wieder die ganz oben genannte Fehlermeldung bekommen.. (Die kommt jetzt aber auch nicht jedes mal, sondern wie gesagt sporadisch). Das erste mal funktioniert dafür jetzt wieder anscheinend immer.Den acceptor habe ich da rausgezogen, damit ich den Thread ganz normal beenden kann. Wie mache ich das denn ohne den? Wenn ich auf den Thread detach aufrufe, dann bekomme ich eine Zugriffsverletzung, welche vom acceptor herrührt.
Ich will sozusagen bei dir in der main des Servers eine Schleife haben, wo auf eine Konsoleneingabe gewartet wird. Und je nach dem kann man mit einer Eingabe dann den Server beenden. Dieser muss dafür aber auch den Thread beenden, was ja nicht geht, wenn der acceptor immer noch wartet. Das geht, wenn ich den acceptor raus nehme und dann kann ich da brav cancel und close auf den acceptor aufrufen und dann kann auch der Thread beendet werden. Allerdings habe ich dann wieder das Problem, dass das connecten nicht jedes mal funktioniert.. (geht ja auch nicht immer, wenn der acceptor in der Funktion ist..)
Mir scheint das alles sehr verzwickt zu sein, die eine Lösung für ein Problem andere Probleme erzeugt, welche nur gelöst werden können, wenn ich wieder auf den Ursprung zurück gehe..

-
Ich sag ja, Du solltest die asynchronen Operationen benutzen. ASIO, das sagt schon der Name, ist für asynchrones IO optimiert.
Die synchronen Operationen kann man nicht mit ordentlichen Mitteln unterbrechen.
Wenn man z.B. ein
acceptsauber beenden will, ist der einzige Weg der mir einfällt, lokal einen Socket zu verbinden, und vorher durch ein Flag dafür zu sorgen, dass kein weiteres Malacceptaufgerufen wird. Man kann den Thread in dem dasacceptläuft natürlich auch einfach abwürgen, aber das ist mal richtig übel.Bei async_accept reicht ein
acceptor.close(), und ggf. aktive Handler kommen mit operation aborted zurück.Der Code wird auch nicht wesentlich komplizierter. Dafür bekommst Du für die I/O-Operationen die jeweils optimale Strategie der benutzen Plattform.
-
Hehe. OK, ja das mit dem ASIO macht Sinn.

Aber ich verstehe trotzdem nicht, warum bei mir der Code nicht geht und warum die diese Fehlermeldung bekomme..
Das blöde ist halt, dass mir das keine Ruhe lässt, bis ich weiss, woran es lag. Ich machs nachher mal mit dem async, aber naja.. Ich will wissen WARUM er mir da keine Verbindung aufbauen kann..Naja. Auf jeden Fall schon mal vielen Dank für die Hilfe!
Vielleicht meldet sich sonst noch jemand, der Ahung von asio hat.
Nur noch kurz dem Grund, warum ich da synchrone Zugriffe habe. Ich denke halt einfach, warum sollte ich das asynchron machen, wenn ich es ja genau so synchron haben will? Grundsätzlich soll da ja gewartet werden bis etwas kommt und sonst soll einfach nix gemacht werden.
-
drakon schrieb:
Ich denke halt einfach, warum sollte ich das asynchron machen, wenn ich es ja genau so synchron haben will? Grundsätzlich soll da ja gewartet werden bis etwas kommt und sonst soll einfach nix gemacht werden.
Du hast ja nichts wirklich Synchrones. Du baust Dir der asynchronen Teil umständlich selbst nach, indem Du synchrone Operationen in einen Worker-Thread auslagerst. Zumindest sagtest Du oben, dass Du das
acceptin einem Thread rennen lassen willst. Du willst es also asynchron.
Zu Deinem Problem: Zeig' nochmal das accept-Dingens, so wie Du es jetzt wirklich hast.
-
Jup. Das mit dem eigenen Thread ist mir dann auch in den Sinn gekommen, dass das eigl. asynchron nachspielt.
(aber ich meinte halt auch den ganzen Rest, welcher nicht wirklich asynchron sein muss)Hier, wies jetzt iwie aussieht:
http://codepad.org/HxdukNNxWenn ich im Server die asynchrone Version des accepting laufen lasse, dann kriege ich mit dem Client keine Verbindung mehr. Dann bekomme ich immer den Fehler, den ich bereits genannt habe..
Und beim Teil mit dem Thread kriege ich manchmal eine Verbindung (beim ersten mal immer) und irgendwann dann gar nicht mehr.
btw:
Im synchronen accepting siehst du noch das, was du mit dem Flag angedeutet hast. (hatte ich schon vor deinem Vorschlag so drin ;))
-
Also ich bin jetzt mal komplett auf Tachyons Beispiel zurückgegangen und habe das getestet. Sehr merkwürdiges Bild.
Das erste mal gingen 4 Connects, der 5te ging nicht mehr (gab den obigen Fehler).
Bei dravere scheint der Code (oder besser die Binarys) zu gehen. Also am Code liegts nicht, boost habe ich ebenfalls auf den neusten Stand gebracht, daran liegts auch nicht. OS, hat dravere gesagt hat er WinXP Prof, SP 3 mit/ohne Firewall gehts. Ich habe die gleichen Sachen, aber bei mir gehts nicht. Andere Firewall, wie die Standard von MS habe ich nicht aktiviert.
Ich habe echt keine Idee mehr, an was es liegen könnte. Jemand sonst eine gute (oder überhaupt eine) Idee?
Ich probier das ganze Morgen mal auf einem anderen PC. Langsam nervts mich..

/EDIT:
Auf meinem Netbook funktioniert das ganze ebenfalls wunderbar.. Aber einfach hier nicht.. Anyone ne Idee, welche Einstellungen das scheinen zu sein?
-
Niemand mehr eine Idee, wo ich den Fehler suchen könnte?
Wie gesagt. An dem Code wirds nicht liegen, sondern an irgendwelchen Einstellungen, aber ich wüsste nicht, was ich, was das anbelangt anderst eingestellt haben könnte..

-
Also ich habe den Fehler nun. Es lag anscheinend daran, dass Zonealarm da irgendwas durch eine Hintertür blockiert, obwohl das Programm gar nicht läuft. Deinstallation hat geholfen.
Danke nochmal an Tachyon!
-
-
HeFails schrieb:
drakon schrieb:
Zonealarm
Ich hatte das Programm nicht zu meinem Schutz auf dem PC und habe ich daher auch nicht wirklich benutzt.
