Funktion wir überlagert. HELP!
-
###################################################################### # 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.
-
Und der ansatz mit dem autoconnecten geht auch nicht.
-
vergiss alles was ich gesagt habe. hat dein dialog den du _vor_ app.exec() aufrufst eine eigene eventqueue?
-
Achso, dann sollte der Slot aber on_pushButton_connect_clicked() heissen.
Leider funktioniert das auch nicht. Ich habe gerade festgestellt, dass es bei mir nicht klappt auch nur irgendeinen Slot aufzurufen.