Funktion wir überlagert. HELP!
-
okey, nun funktioniert mein messenger ja ganz gut.
Jetzt will ich noch per Qt eine schöne GUI dazu programmieren.
Qt verwendet, um Ereignisse abzuhandeln, dieses SIGNAL-SLOT-Zeugs.
Leider verdeckt die Qt-Funktion "bool connect(...)", meine winsock_2-Funktion "connect(...)".
Bei Compilieren sagt er mir dann immer, das es die connect nicht gibt.
Kann mir bitte jemand auf die sprünge helfen, wie ich das beheben kann?
-
schein mich wohl wieder geirrt zu haben.
Neue Frage: Wie kann ich bei einem "make", eine bibliothek mit linken?
zur Errinnerung, man muss der reihe nach:
qmake -project qmake make
ausführen.
Wo und vorallem wie muss ich dort eine Bibliothek anfügen? Bzw. wenn ich die mit ins Maefile reinschreiben muss, wo muss die dann hin?
Mein Makefile(achtung, sehr langer Text, entschuldigung):
############################################################################# # Makefile for building: server # Generated by qmake (2.01a) (Qt 4.3.0) on: So 17. Feb 09:30:17 2008 # Project: server.pro # Template: app # Command: c:\Programme\Qt\4.3.0\bin\qmake.exe -win32 -o Makefile server.pro ############################################################################# first: release install: release-install uninstall: release-uninstall MAKEFILE = Makefile QMAKE = c:\Programme\Qt\4.3.0\bin\qmake.exe DEL_FILE = del CHK_DIR_EXISTS= if not exist MKDIR = mkdir COPY = copy /y COPY_FILE = $(COPY) COPY_DIR = xcopy /s /q /y /i INSTALL_FILE = $(COPY_FILE) INSTALL_PROGRAM = $(COPY_FILE) INSTALL_DIR = $(COPY_DIR) DEL_FILE = del SYMLINK = DEL_DIR = rmdir MOVE = move CHK_DIR_EXISTS= if not exist MKDIR = mkdir SUBTARGETS = \ release \ debug release: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release release-make_default: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release release-make_first: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release first release-all: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release all release-clean: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release clean release-distclean: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release distclean release-install: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release install release-uninstall: $(MAKEFILE).Release FORCE $(MAKE) -f $(MAKEFILE).Release uninstall debug: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug debug-make_default: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug debug-make_first: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug first debug-all: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug all debug-clean: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug clean debug-distclean: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug distclean debug-install: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug install debug-uninstall: $(MAKEFILE).Debug FORCE $(MAKE) -f $(MAKEFILE).Debug uninstall Makefile: server.pro c:\Programme\Qt\4.3.0\mkspecs\win32-g++\qmake.conf c:\Programme\Qt\4.3.0\mkspecs\qconfig.pri \ c:\Programme\Qt\4.3.0\mkspecs\features\qt_functions.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\qt_config.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\exclusive_builds.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\default_pre.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\win32\default_pre.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\release.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\debug_and_release.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\default_post.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\win32\rtti.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\win32\exceptions.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\win32\stl.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\shared.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\warn_on.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\qt.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\win32\thread.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\moc.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\win32\windows.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\resources.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\uic.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\yacc.prf \ c:\Programme\Qt\4.3.0\mkspecs\features\lex.prf \ c:\Programme\Qt\4.3.0\lib\qtmain.prl $(QMAKE) -win32 -o Makefile server.pro c:\Programme\Qt\4.3.0\mkspecs\qconfig.pri: c:\Programme\Qt\4.3.0\mkspecs\features\qt_functions.prf: c:\Programme\Qt\4.3.0\mkspecs\features\qt_config.prf: c:\Programme\Qt\4.3.0\mkspecs\features\exclusive_builds.prf: c:\Programme\Qt\4.3.0\mkspecs\features\default_pre.prf: c:\Programme\Qt\4.3.0\mkspecs\features\win32\default_pre.prf: c:\Programme\Qt\4.3.0\mkspecs\features\release.prf: c:\Programme\Qt\4.3.0\mkspecs\features\debug_and_release.prf: c:\Programme\Qt\4.3.0\mkspecs\features\default_post.prf: c:\Programme\Qt\4.3.0\mkspecs\features\win32\rtti.prf: c:\Programme\Qt\4.3.0\mkspecs\features\win32\exceptions.prf: c:\Programme\Qt\4.3.0\mkspecs\features\win32\stl.prf: c:\Programme\Qt\4.3.0\mkspecs\features\shared.prf: c:\Programme\Qt\4.3.0\mkspecs\features\warn_on.prf: c:\Programme\Qt\4.3.0\mkspecs\features\qt.prf: c:\Programme\Qt\4.3.0\mkspecs\features\win32\thread.prf: c:\Programme\Qt\4.3.0\mkspecs\features\moc.prf: c:\Programme\Qt\4.3.0\mkspecs\features\win32\windows.prf: c:\Programme\Qt\4.3.0\mkspecs\features\resources.prf: c:\Programme\Qt\4.3.0\mkspecs\features\uic.prf: c:\Programme\Qt\4.3.0\mkspecs\features\yacc.prf: c:\Programme\Qt\4.3.0\mkspecs\features\lex.prf: c:\Programme\Qt\4.3.0\lib\qtmain.prl: qmake: qmake_all FORCE @$(QMAKE) -win32 -o Makefile server.pro qmake_all: FORCE make_default: release-make_default debug-make_default FORCE make_first: release-make_first debug-make_first FORCE all: release-all debug-all FORCE clean: release-clean debug-clean FORCE distclean: release-distclean debug-distclean FORCE -$(DEL_FILE) Makefile release-mocclean: $(MAKEFILE).Release $(MAKE) -f $(MAKEFILE).Release mocclean debug-mocclean: $(MAKEFILE).Debug $(MAKE) -f $(MAKEFILE).Debug mocclean mocclean: release-mocclean debug-mocclean release-mocables: $(MAKEFILE).Release $(MAKE) -f $(MAKEFILE).Release mocables debug-mocables: $(MAKEFILE).Debug $(MAKE) -f $(MAKEFILE).Debug mocables mocables: release-mocables debug-mocables FORCE: $(MAKEFILE).Release: Makefile $(MAKEFILE).Debug: Makefile
-
im .pro file
LIBS += -l<library>
hinzufügen
-
###################################################################### # Automatically generated by qmake (2.01a) So 17. Feb 09:30:14 2008 ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input HEADERS += server.h FORMS += server.ui SOURCES += main.cpp server.cpp LIBS += -l lws2_32.lib
So? Weil irgendwie klappt es bei mir immernoch nicht.
-
Danke, es geht.
###################################################################### # Automatically generated by qmake (2.01a) So 17. Feb 09:30:14 2008 ###################################################################### TEMPLATE = app TARGET = DEPENDPATH += . INCLUDEPATH += . # Input HEADERS += server.h FORMS += server.ui SOURCES += main.cpp server.cpp LIBS += -lws2_32
-
Nur leider, findet er die funktion connect(...) immernoch nicht.
Der Code dazu:
rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));
Die Compiler-fehler:
server.cpp:157: error: no matching function for call to `server::connect(SOCKET& , SOCKADDR*, unsigned int)' c:/Programme/Qt/4.3.0/include/QtCore/../../src/corelib/kernel/qobject.h:176: not e: candidates are: static bool QObject::connect(const QObject*, const char*, con st QObject*, const char*, Qt::ConnectionType) c:/Programme/Qt/4.3.0/include/QtCore/../../src/corelib/kernel/qobject.h:278: not e: bool QObject::connect(const QObject*, const char*, const char *, Qt::ConnectionType) const
-
dann versuch doch mal ::connect (wenn die socket-connect funktion im globalen namensraum liegt)
-
Danke, danke! Das scheint erstmal alles zu funzen.
Nun habe ich die folgende Funktion, welche eine verbindung erfragen soll. Dies gschieht per Knopfdruck.
void server::OpenConnection() { long rc = 0; char buf[36]; char target[16]; SOCKADDR_IN addr; //meine Socketadresse textEdit_log->append(QString("aufruf OpenConnection()")); memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 for(int i = 0; i < lineEdit_IP->text().count(); i++) target[i] = lineEdit_IP->text()[i].toAscii(); rc= ::connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if (rc==SOCKET_ERROR) { textEdit_log->append(QString("Kann keine Verbindung herstellen")); return ; } else { textEdit_log->append(QString("Verbindung hergestellt")); } //sende meinen Namen als begrüßung rc = send(s,name,21,0); //empfange den Namen des anderen rc = recv(s,buf, 21, 0); //schreibe den Namen in einen Puffer und hänge am anfang jeder //einkommenden Nachrich <name> : an return ; }
und im Konstruktor wird auch entsprechend connected
server::server(char *n) { setupUi(this); connect(pushButton_connect, SIGNAL(clicked()), this, SLOT(OpenConnection())); long rc; s = INVALID_SOCKET; acceptSocket = INVALID_SOCKET; SOCKADDR_IN addr; //erstelle einen QCounter, welcher immer wieder void receivemsg(); aufruft. name = new(char[20]); for (int i = 0; i < 20; i++) name[i] = n[i]; name[20] = '\0'; // Winsock starten rc=startWinsock(); if (rc!=0) { ... } }
nur leider passiert nichts, wenn ich auf den button drücke O_o. Nichmal die meldung welche mir sichert, dass er gedrückt wurde, kommt. Schade, sehr schade.
-
dein programm versucht sich mit der IP 255.255.255.255 zu verbinden, und das kann dauern
edit: natürlich nicht
0.0.0.0 ist es
verdammt, ich brauch kaffee
-
Ah, d**n. Hast natürlich vollkommen Recht. Habe das Programm modifizieren müssen, solange connect nicht funzte, habs leider vergessen, ses wieder rückgängig zu machen:
void server::OpenConnection() { long rc = 0; char buf[36]; char target[16]; SOCKADDR_IN addr; //meine Socketadresse textEdit_log->append(QString("OpenConnection()")); memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 for(int i = 0; i < lineEdit_IP->text().size(); i++) target[i] = lineEdit_IP->text()[i].toAscii(); addr.sin_addr.s_addr=inet_addr( target); rc= ::connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if (rc==SOCKET_ERROR) { textEdit_log->append(QString("Kann keine Verbindung herstellen")); return ; } else { textEdit_log->append(QString("Verbindung hergestellt")); } //sende meinen Namen als begrüßung rc = send(s,name,21,0); //empfange den Namen des anderen rc = recv(s,buf, 21, 0); //schiebe den Namen im buffer 16 zeichen nach rechts return ; }
Fazit: Geht leider immer noch nicht.
Problem: Das selbe
-
nutze lieber
struct hostent* hostinfo; hostinfo = gethostbyname("hostname"); if (hostinfo == NULL) { close(local_socket); } else neu.sin_addr = *(struct in_addr*) hostinfo->h_addr;
als "hostname" kannst du die ip als string oder einen hostnamen übergeben. gethostbyname() kümmert sich dann um die namensauflösung via dns.
-
Gute Idee, danke. Hilft mir aber bei meinem Problem nicht viel weiter.
-
5000_Watt schrieb:
Gute Idee, danke. Hilft mir aber bei meinem Problem nicht viel weiter.
nun, ich weiß ja auch nicht was dein problem ist
deine schilderung "es passiert nichts" kann mich auch nur vermuten lassen
-
Ich könnte ja den gesamten Quellcode posten. Aber ich glaube, da gibts s welche, die mir das übel nehemn würden
nun, ich weiß ja auch nicht was dein problem ist
deine schilderung "es passiert nichts" kann mich auch nur vermuten lassen :].
Gut, dann poste ich eine ausgabe meines programmes.
Winsock gestartet!
Socket erstellt!
Socket an port 12345 gebunden
acceptSocket ist im listen Modus....wenn ich den button drücke:
Winsock gestartet!
Socket erstellt!
Socket an port 12345 gebunden
acceptSocket ist im listen Modus....das gleiche. es ist also nichts passiert
.
Die Methode OpenConnection() kennste ja schon, also kommt hier noch der Volständige Konstruktor sowie die main.cpp:
Konstruktor:
server::server(char *n) { long rc; s = INVALID_SOCKET; acceptSocket = INVALID_SOCKET; SOCKADDR_IN addr; setupUi(this); connect(pushButton_connect, SIGNAL(clicked()), this, SLOT(OpenConnection())); name = new(char[21]); for (int i = 0; i < 20; i++) name[i] = n[i]; name[20] = '\0'; //den Timer zum automatischen akzeptieren einer Verbindung aktivieren accept_timer = new(QTimer)(this); connect(accept_timer, SIGNAL(timeout()), this, SLOT(CheckForNewConnections())); accept_timer->start(100); // Winsock starten rc=startWinsock(); if (rc!=0) { textEdit_log->append(QString("Fehler: startWinsock, fehler code:")); return; } else { textEdit_log->append(QString("Winsock gestartet!")); } // Socket erstellen acceptSocket=socket(AF_INET,SOCK_STREAM,0); if (acceptSocket==INVALID_SOCKET) { textEdit_log->append(QString("Fehler: Der Socket konnte nicht erstellt werden, fehler code: ")); return ; } else { textEdit_log->append(QString("Socket erstellt!")); } //Socket an 12345 binden memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(12345); addr.sin_addr.s_addr=ADDR_ANY; rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); if (rc==SOCKET_ERROR) { textEdit_log->append(QString("Fehler: bind, fehler code: ")); return; } else { textEdit_log->append(QString("Socket an port 12345 gebunden")); } rc=listen(acceptSocket,10); if (rc==SOCKET_ERROR) { textEdit_log->append(QString("Fehler: listen, fehler code: ")); return; } else { textEdit_log->append(QString("acceptSocket ist im listen Modus....")); } }
main.cpp:
#include <QApplication> #include "server.h" #include <iostream> int main(int argc, char *argv[]) { char name[21] = {'S','e','r','v','e','r','\0'}; QApplication app(argc,argv); server *dialog = new server(name); dialog->show(); return app.exec(); }
Der rest sollte nicht relevant sein, weil er nicht aufgerufen wird/werden soll.
-
beim server socket
addr.sin_addr.s_addr = htonl(INADDR_ANY);
verwenden
wieso gibt das programm nach dem klick auf den button
Winsock gestartet!
Socket erstellt!
Socket an port 12345 gebunden
acceptSocket ist im listen Modus....aus? das geht aus deinem code eigentlich nicht hervor.
-
Damit meie ich immer die gesamtausgabe. Also das, was schon da war + die neue Ausgabe.
-
Danke, leider muss ich mittteilen: Es geht immer noch nicht.
-
ahh. probiers mal mit
connect(pushButton_connect, SIGNAL(clicked()), this, SLOT(OpenConnection(void)));
oder nenne den slot
on_pushButton_clicked()
dann connected qt das automatisch
-
Hab ich.
Die Methode heißt jetzt OpenNewSocketConnection(). Und selbst wenn es eine Namensdopelung gäbe, hätte ich dann nicht die alste Methode überladen?
-
darum ging es mir nicht. es ist wichtig dass beim connecten von signals und slots die parametertypen _exakt_ übereinstimmen. ansonsten wird der slot nicht ausgeführt.
wenn du also OpenConnection so deklariert hast:
class
{
private slots:void OpenConnection(void);
}dann musst du auch
connect(pushButton_connect, SIGNAL(clicked()), this, SLOT(OpenConnection(void)));
benutzen. nichtsdestotrotz ist es bei ui-komponenten einfacher die slots so zu benennen:
on_<widgetname>_<signal>()
also eben zum beispiel
on_pushButton_clicked()
dann benötigst du auch kein aufruf von connect() mehr.