Tcpsocket newbie
-
Hey everyone, I'm working on an app that should receive 10 integer data values over a tcp connection.
I've never dealt with networking and was looking to send a single value of a horizontal slider over the network for testing purposes.
My current code is:#include "singleslider.h" #include "ui_singleslider.h" singleslider::singleslider(QWidget *parent) : QMainWindow(parent), ui(new Ui::singleslider) { socket = new QTcpSocket(this); ui->setupUi(this); server = new QTcpServer(this); if(!server->listen(QHostAddress::Any,1234)) { qDebug()<< "not started"; } else { qDebug() << "Server Started"; socket = server->nextPendingConnection(); } } singleslider::~singleslider() { delete ui; } void singleslider::on_horizontalSlider_valueChanged(int value) { socket->write("3"); socket->flush(); }
I was having difficulty sending the actual value so I tried to trivialize the problem to sending a single value "3". Unfortunately, even this code causes the application to crash upon moving the horizontal slider.
Anyone have any advice. Thanks.
For more context, the client side code is as follows: ``` void MainWindow::Connect() { socket = new QTcpSocket(this); connect(socket, SIGNAL(readyRead()), this, SLOT(changeSomething())); socket->connectToHost("10.121.124.218", 1234); if(socket->waitForConnected(3000)) { qDebug() << "Connected"; } else { qDebug() << "Not Connected"; } } void MainWindow::changeSomething() { qDebug() << "Socket as something to read"; while(socket->bytesAvailable() > 0) { //Test to see if socket is reading socket->readAll(); rpm1_needle->setCurrentValue(5); } } ```
-
Hi and welcome
Nothing really shouted "crash!" looking at you code.
so when it calls ( because u touch the slider)void singleslider::on_horizontalSlider_valueChanged(int value) >>> socket->write("3"); <<< it crashes here?
and socket is a member of singleslider:: and
the one you new in constructor
socket = new QTcpSocket(this); ? -
-
@dflass
Hello,
One thing that peeked my attention is this constructor:socket = new QTcpSocket(this); // <<< This is never(!) used // ... if (!server->listen(QHostAddress::Any,1234)) { qDebug()<< "not started"; } else { qDebug() << "Server Started"; socket = server->nextPendingConnection(); // <<< Are you sure that you have a pending connection? No pending connection means setting the socket variable to NULL }
You have the following problem(s):
- You create a socket that you never intend to use (the first line is exactly that).
- You request the next pending connection, even though you're not sure if such a connection is queued (the function returns
NULL
and sets yourQSqlSocket
pointer toNULL
). - You try to dereference a NULL pointer:
void singleslider::on_horizontalSlider_valueChanged(int value) { socket->write("3"); // <<< It crashes here because socket is NULL }
To have that working properly, connect the QTcpServer::newConnection signal to a slot in your program and only then retrieve the socket handle.
Kind regards.
-
Yes, firstly I'm trying to get something to be successful before worrying about data streams.
Does the if else statement not prevent a the null pointer?
It seems as if there is not an incoming connection the qDebug will just output "not started" -
There are a couple of open issues in your code.
@kshegunov tries already to point you to the problem of your listen use.
When the port 1234 is available it will return true. But that does not mean that there is already a waiting connection. Therefore the nextPendngConnection will return a null pointer. You need to use signals and slots.
Therefore I am suggesting to you to go through the network fortune server and fortune client examples.Once again the difference between sending a char containing the ASCII representation of '3' and sending an integer holding 3 is very significant. The char is one byte and the integer would be probably in this case 4 bytes.
int i = 3; char chr = i; // equivalent to char chr = 3; char chr3 = '3';
You can do above code. A conversion between integers and chars is done here by the compiler. In most circustances it will complain and issue at least some warnings. However, you can do this.
However, you cannot do this over a TCP connection. When sending a char you need to read on the other side a char and the same with ints. -
Does the if else statement not prevent a the null pointer?
Well, not really, no. QTcpServer::listen doesn't block, its return value just indicates whether or not your request to listen to a port was successful. This doesn't at all guarantee that you have pending connections for that server socket. As @koahnig pointed out, you should use signals and slots to connect to the interesting events generated by your server socket and handle them appropriately. Do follow his suggestion, and look at the server/client examples, which will give you a good overview on how to setup a TCP server/client application properly.
Kind regards.