[C++] eenvoudige TCP socket geraakt niet verbonden (in Qt)

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 16-09 21:29
Dag allen!

Ik zit al een hele tijd te zoeken achter de reden waarom ik geen data via TCP verstuurd krijg in een programma'tje dat ik aan het schrijven ben. Ik heb gekeken in Wireshark, en ook daar kan ik geen verzonden TCP pakketten van mijn applicatie zien. (De UDP pakketten komen wél door).

Eerst dacht ik dat het oftewel een firewall probleem kon zijn, oftewel dat ik ergens een gigantische fout over het hoofd zou gezien hebben in mijn code.

Ik heb dan om te testen een nieuw project aangemaakt waarbij het programma een heel basic TCP verbinding opzet met zichzelf, en data probeert te versturen, waarbij hij in console print als hij op een bepaalde regel is geraakt. Wat bleek? Hij blijft steken bij "waitForConnected()".

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void MainWindow::readTcpData()
{
    QByteArray data = pSocket->readAll();
    QD << data;
}
void MainWindow::on_pushButton_clicked()
{
    QByteArray data;
    data.append("test");

    pSocket = new QTcpSocket( this ); 
    connect( pSocket, SIGNAL(readyRead()), SLOT(readTcpData()) );

    QD << "button clicked";

     pSocket->connectToHost("127.0.0.1", 9000);
     if( pSocket->waitForConnected() ) {
         QD << "connected";
         pSocket->write( data );
     }
}


"button clicked" krijg ik in console te zien als ik op de knop klik. "connected" komt er niet op.
Iemand die een eenvoudige verklaring hiervoor heeft?
(Kans is zeer reëel dat het iets heel stoms is. Ben namelijk nog maar een noob-programmeur ;) )

Alvast bedankt!

Acties:
  • 0 Henk 'm!

  • Gleighton
  • Registratie: November 2008
  • Niet online
waitForConnected wacht zoals de naam al zegt tot dat er een connection is. Heb je op poort 9000 wel een socket open staan om verbinding mee te maken? Je kunt zelf nog een applicatie maken, waarbij je in plaats van connect() je bind() gebruikt om je socket server mee aan te maken.

Ik raad je aan om even goed in te lezen hoe sockets werken, dan kun je ook het verschil tussen TCP en UDP verklaren.

[ Voor 7% gewijzigd door Gleighton op 23-05-2015 18:26 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
Ik weet het niet zeker, maar het kan zijn dat je in Wireshark verkeer naar locahost/127.0.0.1 niet ziet langskomen omdat dit niet echt via een netwerk adapter gaat.

Zie hier : https://wiki.wireshark.org/CaptureSetup/Loopback

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 16-09 21:29
Gleighton: Ik heb de code grof gekopieerd van deze post:
http://stackoverflow.com/...85/simplest-qt-tcp-client
Ik ging er vanuit dat aangzien hij "geconnect" was op die host, dat hij er ook op zou listenen?
Hoe dan ook, ik ben op dit moment wat aan het experimenteren met de functies die jij zegt (Heb ook een 2de applicatie gemaakt). Heb hier en daar wel al wat nuttige zaken gevonden, maar heb nog steeds niet door hoe ik ervoor zorg dat ik de connection bevestig. Ik post morgen nog een update of het al dan niet gelukt is ;)

@Farlane: ik heb in Wireshark "Capture on all interfaces" aangevinkt. Deze zou ook localhost moeten zien. Maar ook met het gewone IP (dat ik in een ander programma doorgaf) kon hij geen TCP packets zien. UDP ziet hij echter wel...

Maar... vraagje: die connectToHost(), moet ik die normaal gezien ook niet kunnen zien in Wireshark? Of negeert Wireshark dat soort pakketten?


EDIT: bijkomend vraagje: als ik bidirectionele communicatie wil hebben. Klinkt het dan logisch dat ik op beide programma's zowel een Socket als een Server nodig heb?

[ Voor 8% gewijzigd door Opifex op 24-05-2015 00:11 ]


Acties:
  • 0 Henk 'm!

  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

azziplekkus schreef op zaterdag 23 mei 2015 @ 23:21:
Maar... vraagje: die connectToHost(), moet ik die normaal gezien ook niet kunnen zien in Wireshark? Of negeert Wireshark dat soort pakketten?
Nee, die moet hij kunnen zien. Het is een TCP-pakketje met de SYN-vlag gezet, en zonder payload (data). Of dat pakketje verstuurd wordt is niet afhankelijk van of de server wel of niet werkt, want dat krijgt de client pas te horen ná dat pakketje.
EDIT: bijkomend vraagje: als ik bidirectionele communicatie wil hebben. Klinkt het dan logisch dat ik op beide programma's zowel een Socket als een Server nodig heb?
1). Socket en server zijn verschillende begrippen, je hebt een client en server, en beiden hebben een socket. Een server doet met zijn socket een bind en listen, en een client doet daarna met zijn socket een connect (en eventueel vooraf nog een bind, maar dat hoeft meestal niet).
2) Nee je hebt niet aan allebei de kanten een server en client. Server/client geeft alleen wie er actief verbindt, en wie alleen luistert naar inkomende verbindingen. Zodra een client verbonden heeft met een server heb je gratis en voor niets een bi-directionele verbinding.

Heeft geen speciale krachten en is daar erg boos over.


Acties:
  • 0 Henk 'm!

  • Basti504
  • Registratie: Februari 2005
  • Laatst online: 18-09 20:31

Basti504

Niet de enige, wel de echte.

Om socket verbindingen te testen heb ik laatst dit tooltje gebruikt:

http://www.hw-group.com/products/hercules/index_en.html

Hiermee kon ik mijn programma, "TCP client", testen zonder de echte "TCP server". Wat in dit geval een vision camera was die 0 debug mogelijkheden had.

De TCP server in dat tooltje geeft precies weer wanneer TCP verbindingen opgezet worden door een client en wat er precies verstuurd wordt. En kan op commando ook data terugsturen.

...


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 16-09 22:43
azziplekkus schreef op zaterdag 23 mei 2015 @ 23:21:
@Farlane: ik heb in Wireshark "Capture on all interfaces" aangevinkt. Deze zou ook localhost moeten zien. Maar ook met het gewone IP (dat ik in een ander programma doorgaf) kon hij geen TCP packets zien. UDP ziet hij echter wel...
Volgens mij ligt het er aan via welke interface het verkeer loopt : als het via de loopback interface gaat worden de packets helegaar niet verzonden maar via de kernel in memory getransporteerd. Of zoiets.

Check ff de link zou ik zeggen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Gleighton
  • Registratie: November 2008
  • Niet online
Onder windows kun je inderdaad niet zomaar de loopback interface volgen. Hiervoor moet je inderdaad doen wat farlane zegt.

Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 16-09 21:29
Het is me ondertussen gelukt om een werkende communicatie opgezet te krijgen! :)
Bedankt voor de hulp iedereen!
bwerg schreef op zondag 24 mei 2015 @ 10:36:

1). Socket en server zijn verschillende begrippen, je hebt een client en server, en beiden hebben een socket. Een server doet met zijn socket een bind en listen, en een client doet daarna met zijn socket een connect (en eventueel vooraf nog een bind, maar dat hoeft meestal niet).
2) Nee je hebt niet aan allebei de kanten een server en client. Server/client geeft alleen wie er actief verbindt, en wie alleen luistert naar inkomende verbindingen. Zodra een client verbonden heeft met een server heb je gratis en voor niets een bi-directionele verbinding.
Thing is dat er in Qt een QTcpServer en een QTcpSocket klasse zijn. Ik heb aan beide kanten (client en server, of specifiek voor mijn toepassing beter master en slave) beide klasses nodig gehad. Anders kon ik alleen zenden of alleen versturen. Om bvb. de slave te laten antwoorden doe ik ongeveer dit:
socketPtr = serverPtr->nextPendingConnection()
(Heb de exacte code niet op deze pc staan, dus kan ze niet copy pasten)

Acties:
  • 0 Henk 'm!

  • Gleighton
  • Registratie: November 2008
  • Niet online
Verschil tussen de QTcpServer en QTcpSocket is wat ik zo zie dat de QTcpServer met meerdere sockets tegelijkertijd kan op laten zetten. Dit in tegenstelling toch een QTcpSocket, welke je aan de ene kant kunt binden en als er verbinding is dan ook maar verbonden zijn met een client.

Het komt er dus op neer dat als je meerdere clients verbinding wil hebben met een centrale applicatie dat je dan de server variant moet pakken en als je maar één op één verbinding wil hebben een gewone socket voldoende is.

Acties:
  • 0 Henk 'm!

  • Opifex
  • Registratie: September 2013
  • Laatst online: 16-09 21:29
De QTcpServer klasse heeft heel andere functies, variabelen, signals en slots dan de QTcpSocket klasse.
Dit komt ook omdat QTcpServer rechtstreeks inherit van QObject, en QTcpServer van QAbstractSocket en QIODevice.
Pagina: 1