PDA

View Full Version : Windows Application and Embbeded system communication using TCP protocol



nagabathula
13th August 2011, 10:05
Hello every one i am working on a project where i have to create a Application to control a Embedded System using TCP protocol. The embedded system runs on a ARM 9 processor on which they have flashed a TCP stack, There is a IP address and ID for the processor. Now my problem is what i should use a QTcpSocket or a QTcpServer cause i will be sending some control commands to the embbeded system and it will reply back to me the status of its sub systems.. So there will be both sending and receiving of data. The Network example only describe how to either send data using QTcpServer or receive data using QTcpSocket. Should i use both QTcpSocket and QTcpServer in my program to communicate both ways. .?? Pls suggest me something this is the first time i am working on a networking project.

Thank you

Santosh Reddy
15th August 2011, 06:52
Well, First thing this is nothing to do with Qt. It is simple socket programming. Let us see if I can explain you some basic things and get you started.

1. For a TCP commutation to happen a TCP connection has to made.
2. For a TCP connection, a client requests for a connection, and a server (which is already listening) has to accept the connection.
In your case, the embedded system has to act as a server, and keep listening to incoming connection requests. The PC application makes a request to the server (embedded system), and connection is established. Now data can be sent and received, both ways, as long as connection is active. So you can use QTcpSocket at the client end, i.e. PC application, and use QTcpServer & QTcpSocket at the server end, i.e. embedded system end. This way you could connect any number of PC's to the embedded system. (as long as embedded system can accept new connections)

You could also make the PC as server, and embedded system as client, which will make it possible to connect many embedded systems to one PC. Again it all depends how you want to design you application

I suggest read some socket/netwok programming basics, else you will be lost figuring out how things work.

marcvanriet
15th August 2011, 20:50
Hi,

As Santosh said, you must first have a server listening on a port.

You can also have the server running on the PC side. Then your client (the ARM board) can connect to the server at that port. But the actual communication doesn't occur on this port. For every client that connects to the server, a new QTcpSocket must be created that you can use for sending and receiving data to/from the client connection.

It is better to have the server running on the ARM, but I can't comment on this. If you get a server to work on the ARM, you must only open a QTcpSocket in Qt.

If you look at the Fortune Cookie example in Qt, you will see that the client connection is closed immediately. So this is not what you want.

I can give you some code snippets of a project of mine. It shows that for every new incoming client connection, a new object is created that holds information about the newly created connection to the client.

Note that it is not a fully working example, it is just to show how I did some things to keep the client connection open.

Regards,
Marc



/** TCP server that listens for incoming client connections.
*/
class CMyTcpServer : public QObject
{
Q_OBJECT
public:
explicit CMyTcpServer(QObject *parent = 0);
QTcpServer *tcpServer;
QString m_sIpAddress;
int m_nIpPort;
QList<CMyTcpClientConnection*> m_lClients;
void removeClient( CMyTcpClientConnection *pClient );
public slots:
void serverNewConnection( void );
};

/** Client connection of a CMyTcpServer.
*/
class CMyTcpClientConnection : public QObject
{
Q_OBJECT
public:
explicit CMyTcpClientConnection( CMyTcpServer *parent, QTcpSocket *clientSocket );
CMyTcpServer *m_pTcpServer;
QTcpSocket *m_pSocket;
public slots:
void doDisconnect( void );
void doReadyRead( void );
};



//------ CMyTcpServer() --------------------

CMyTcpServer::CMyTcpServer(QObject *parent) :
QObject(parent)
{
tcpServer = new QTcpServer(this);

if( !tcpServer->listen() ) // unable to start server
do stuff if TCP server cannot be started

connect(tcpServer, SIGNAL(newConnection()), this, SLOT(serverNewConnection()) );
}

//----------- serverNewConnection -------------------
/** Signal handler for newConnection() when a new connection is requested.
* A new client connection object is created and added to the client list.
*/
void CMyTcpServer::serverNewConnection( void )
{
CMyTcpClientConnection *clientConnection = new CMyTcpClientConnection( this, tcpServer->nextPendingConnection() );

m_lClients.append( clientConnection );
}

//------------------------------------- removeClient --------------------------
/** Removes a specified client from the client list.
* This is called by the client when its connection is closed.
*/
void CMyTcpServer::removeClient( CMyTcpClientConnection *pClient )
{
int nIndex = m_lClients.indexOf( pClient ); // find position of client in list
if( nIndex >= 0 )
{
qDebug() << "client removed";
m_lClients.removeAt( nIndex ); // remove from list
pClient->deleteLater(); // delete object itself also
}
}

//=======================================
// CMyTcpClientConnection
//========================================

//------------------------------------- CMyTcpClientConnection ------------
/** Constructor.
* The TCP server is given as parent. It will maintain a list of client
* connections. The new TCP socket is given as parameter too. This is
* remembered by this object, and it becomes the parent of it too.
*/
CMyTcpClientConnection::CMyTcpClientConnection( CMyTcpServer *parent, QTcpSocket *clientSocket ) :
QObject(parent)
{
m_pTcpServer = parent;
m_pSocket = clientSocket;
m_pSocket->setParent( this );

connect(clientSocket, SIGNAL(disconnected()), SLOT(doDisconnect()));
connect(clientSocket, SIGNAL(readyRead()), SLOT(doReadyRead()) );

qDebug() << "add TCP client " << m_pSocket->peerAddress().toString() << m_pSocket->peerPort();
}

//------------------------------------- doDisconnect --------------------------
/** Signal handler when peer is closed.
* Removes this client from the TCP server client connection list.
* This client connection object will then be deleted.
*/
void CMyTcpClientConnection::doDisconnect( void )
{
m_pTcpServer->removeClient( this );
}

//------------------------------------- doReadyRead --------------------------
/** Signal handler when data is available from peer.
*
*/
void CMyTcpClientConnection::doReadyRead( void )
{
QByteArray aData = m_pSocket->readAll(); // read all data from socket
...
}

nagabathula
16th August 2011, 12:26
Hello marcvanriet and Santosh Reddy thank you so much for the code example and the information you both have given me i just have a vague idea about how i should go about it now i will read on socket/netwok programming basics now first before i can start. i think i will use the PC side as the client and the Embedded system as the Server. And in this project they will connect to only a single client.

@marcvanriet-- I din't exactly understand how you always keep the client connection open.

Thank you again Santosh Reddy and marcvanriet for the information you have given me cleared many doubts of mine.

Regards

yeye_olive
16th August 2011, 13:37
@nagabathula


@marcvanriet-- I din't exactly understand how you always keep the client connection open.

The TCP protocol allows the bidirectional transmission of streams of bytes. Each endpoint cannot guess in advance when the stream it receives will end. That is why there is a notion of connection: while the connection is open, each endpoint is prepared to receive additional data. It is only by closing the connection that one endpoint notifies the other that the communication is over.

By contrast, the UDP protocol is used for one-shot communication. A single block of data is transmitted in a single direction. There is no notion of connection here: the receiving end is simply notified that a block of data has arrived; the communication is already over.

The fortune example keeps things simple by using TCP for one-shot communication only. The server sends a fortune and immediately closes the connection.

In general you only close the TCP connection when the communication is definitely over. You can leave it open even if there is no data to transmit immediately.

Using QTCPSocket, call disconnectFromHost() (or delete the object) to close the connection. Use the disconnected() signal to be notified when the connection is closed by the other endpoint.