QTcpSocket connected, but server doesn't receive data
-
Hello everyone.
I am implementing a server with Qt 5.2 which connects to a server implemented in standard C++ (which uses standard linux lib for socket).
My client is connecting to the server without any problems, but when I try to send something, the server doesn't receive anything, and when I look on my network activity with Wireshark, it seems that my client doesn't send anything at all because I only see TCP packet for connection establishement.
The TCP socket is in a separate thread from the GUI, but the socket is created inside this thread, so I don't think it is a thread problem. Plus, when I debug and print the result of write functions it writes 4 or 5 (based on the string I have sent) but doesn't send anything.
Here is my class which contains the thread
ThreadSending.h
@
/**- @brief thread establishing connection with server and sends data to the server
- inherits from QThread
/
class ThreadSending : public QThread
{
Q_OBJECT
public:
/*- @brief constructor, initiliaze IP and port
ThreadSending();
public slots:
/**
* @brief the slot which receives signals sent by MainWindow
*
* @param val the string emitted
*/
void addValueToList(QString val);private:
/**
* @brief method call when the thread starts
*
*/
void run();QString serverIP; /**< the IP of the server */ int portWrite; /**< the port where it connects */ QList <QString> toSend; /**< list of data to send */ QMutex mutex; /**< mutex used to avoid concurrent access on list */
};
@ThreadSending.cpp
@
/**************** Sending thread *********************/
ThreadSending::ThreadSending() : QThread()
{
serverIP = "192.168.0.4";
portWrite = 1234;
}void ThreadSending::addValueToList(QString val)
{
mutex.lock();
toSend.append(val);
qDebug()<<"new value to send : "<<val;
mutex.unlock();
}void ThreadSending::run()
{
QTcpSocket* sckWrite = new QTcpSocket();
sckWrite->connectToHost(serverIP,portWrite);
if(sckWrite->waitForConnected(-1))
{
qDebug()<<"connect sending";
while (true)
{
string data = "";
if(!toSend.isEmpty())
{
mutex.lock();
data = toSend.first().toStdString();toSend.removeFirst(); mutex.unlock(); QString dt = QString::fromStdString(data+"\n"); QByteArray array; array.append(dt); qDebug()<<"state "<<sckWrite->state(); qDebug()<<"send "<<sckWrite->write(array)<<" bytes"; //sckWrite->flush(); //sckWrite->close(); } } } else qDebug()<<"fail to connect sending";
}
@and my main.cpp
@
int main(int argc, char *argv[])
{
qInstallMessageHandler(debugOutput);QApplication a(argc, argv); MainWindow w; w.show(); ThreadSending* ts = new ThreadSending(); //ThreadReceiving* tr = new ThreadReceiving(); QObject::connect(&w, SIGNAL( valueToSend(QString) ), ts, SLOT( addValueToList(QString) )); ts->start(); //tr->start(); return a.exec();
}
@Qt client is running on Windows 7 64bits with Qt5.2.1 and the server is runing on Ubuntu 12.04LTS 32bits
Thank you for your help -
Hi and welcome to devnet,
Can you also post the code from the server ?
-
Thanks a lot.
Here is my server implementation (at least for the communication with the client)
ClientConnection.h
@
#ifndef CLIENTCONNECTION_INCLUDED
#define CLIENTCONNECTION_INCLUDED#include <cstdio>
#include <cstdlib>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>#include "SynchronizedList.h"
class ClientConnectionReading
{
public:
ClientConnectionReading(SynchronizedList* o);
~ClientConnectionReading();void initConnection();
bool waitForClient();
bool waitForDataReception();void connectionLoop();
private:
int sck;
int clientSocket;
int port;
struct sockaddr_in serv_addr;
struct sockaddr_in cli_addr;SynchronizedList* obj;
};#endif // CLIENTCONNECTION_INCLUDED
@ClientConnection.cpp
@
#include "ClientConnection.h"ClientConnectionReading::ClientConnectionReading(SynchronizedList* o)
{
obj = o;
}
ClientConnectionReading::~ClientConnectionReading()
{}
void ClientConnectionReading::initConnection()
{
sck = socket(AF_INET, SOCK_STREAM, 0);
if (sck < 0)
std::cout<<"ERROR opening socket";bzero((char *) &serv_addr, sizeof(serv_addr)); port = 1234; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port);
}
bool ClientConnectionReading::waitForClient()
{
int clilen;
if (bind(sck,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
std::cout << "ERROR on binding";
std::cout << "waiting for client";
listen(sck,5);
clilen = sizeof(cli_addr);
clientSocket = accept(sck, (struct sockaddr ) &cli_addr, (socklen_t)&clilen);
return true;
}
bool ClientConnectionReading::waitForDataReception()
{
int n = 0;
char buffer[256];
do{
bzero(buffer,256);
printf("before read\n");
//sleep(1);
n = read(clientSocket,buffer,255);
printf("after read\n");
//sleep(1);
if(n==-1 || n==0)
{
printf("Error while reading\n");
getchar();//wait for key strike
}printf("received : %s , n : %d\n",buffer,n); obj->addElement( std::string(buffer) ); } while ( true ); return true;
}
void ClientConnectionReading::connectionLoop()
{
std::cout << "launching reading process";
sleep(1);
initConnection();
waitForClient();
waitForDataReception();
}
@and the main
@
#include "ClientConnection.h"
#include "ClientConnectionSending.h"
#include "HardwareCommunication.h"
#include <pthread.h>void* readingThread(void* ptr)
{
ClientConnectionReading* obj = (ClientConnectionReading*)ptr;
obj->connectionLoop();
return NULL;
}void* sendingThread(void* ptr)
{
ClientConnectionSending* obj = (ClientConnectionSending*)ptr;
obj->connectionLoop();
return NULL;
}int main()
{
std::cout<<"start sever"<<std::endl;
pthread_t t_send,t_receive;
SynchronizedList* actionList = new SynchronizedList();
SynchronizedList* sendList = new SynchronizedList();
ClientConnectionReading* read = new ClientConnectionReading(actionList);
ClientConnectionSending* send = new ClientConnectionSending(sendList);
HardwareCommunication hwCom;pthread_create(&t_send,NULL,sendingThread,send);
pthread_create(&t_receive,NULL,readingThread,read);
std::cout << "thread launch, entering main loop"<<std::endl;
while(1) //main thread of the app
{
if(sendList->isEmpty())
{
sleep(1);
}
else
{
std::string val = sendList->getFirstElement();
std::string head = val.substr(0,2);
if(head.compare("x:"))
{
std::string strOffset = val.substr(2);
hwCom.setXaxis( atoi(strOffset.c_str()) );
}
if(head.compare("y:"))
{
std::string strOffset = val.substr(2);
hwCom.setYaxis( atoi(strOffset.c_str()) );
}
if(head.compare("z:"))
{
std::string strOffset = val.substr(2);
hwCom.setZaxis( atoi(strOffset.c_str()) );
}
}
}
delete read;
return 0;
}
@Also I have implemented the following code in Java for testing purpose :
@
package test_serv;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;/**
*-
@author Vince
*/
public class Test_serv {/**
- @param args the command line arguments
*/
public static void main(String[] args) {
Socket sck;
OutputStream os;
try {
String test = "test";
sck = new Socket("192.168.0.4",1234);
os = sck.getOutputStream();
os.write(test.getBytes());
} catch (UnknownHostException ex) {
Logger.getLogger(Test_serv.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Test_serv.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
@
- @param args the command line arguments
And it works (the server receives test correctly).
-
-
One thing that puzzles me is why are you converting a QString to a std string to convert it right after to a QString and then to a QByteArray ?
You also don't provide any means to stop your thread.
I would recommend that you take a look at the Fortune Server/Client examples to have a better understanding on how you can use these classes without the need of threads