I'm working on the project where all 3 devices are running in QNX
2 Socket Client (non blocking) running in One CPU., remaining 2 CPU are running as Server.
When I test run, I see some issues with Client don't receive reply from the Server for certain time, then I have to drop the connection and re-establish.
I have doubt that there are any restriction under the same process, 2 client socket thread can not be running? esp in QNX. If so how to create the process and create the thread on the process for each client.
// Client Side Code
int CNoseCapUnitECUCLient::iStartTCPIPHandler(eNCUOption eOption)
{
printf("Start %s NCU TCPIP Handler handler \n",(meNCUOption == NCU_FREE_AREA) ? "Local":"Remote" );
meNCUOption = eOption;
if(mbTCPHandThreadAlive)
{
iStopTCPIPHandler();
}
else
{
iCreateMutex(mpMainMutex, "TCPIPMutex");
}
// Create new handler thread
mpHandThread = CMNcreateThread();
if(mpHandThread == nullptr)
{
return 1;
}
// Thread priority should at least be equal to LTA application (21)
bool bResult = mpHandThread->create("TCP_HeartbeatThread", 0, 0, 0, &heartBeatThread, this);
if(bResult == false)
{
return 1;
}
mbHandling = true;
mbTCPHandThreadAlive = true;
return EOK;
}
void CNoseCapUnitECUCLient::TCP_HeartbeatThread()
{
int iRecvLen = 0;
unsigned char buf = 55;
strcpy( (char*) Sendbuf, " ECU->NCU Heartbeat\n " );
while(1)
{
CMNOSSleep(1);
mpMainMutex->take(200);
if(!ConnectedToServer)
{
CMNOSSleep(1000); // delay after the connection.
if(connectToNCU())
{
LastRecvTime = localClock_t::now();
ConnectedToServer = true;
}
}
else if(ConnectedToServer)
{
if(std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastSendTime).count() > 50) // HeartBeat
{
SendNCUCommand(msgSetTimerHeartbeat,MSG_NONE, &buf , 1);
}
else
{
strcpy((char*)ucRecvBuf,"");
iRecvLen = recvResponse(ucRecvBuf);
if( iRecvLen > 0)
{
if(strlen((char*)ucRecvBuf) > 0)
{
iRecvError = 0;
if(commState == false)
{
iSetBrightness(LCD_BRIGHTNESS_100PERCENT);
onCommunication(true);
}
ClientRxChar((char*)ucRecvBuf, iRecvLen);
}
}
else if(iRecvLen == 0)
{
iRecvError++;
if(iRecvError >= 5)
{
iRecvError = 0;
}
}
else if(iRecvLen == -1)
{
printf(" ****client Recv Function return false ***** \n" );
iRecvError = 0;
ConnectedToServer = false;
disconnect();
onCommunication(false);
}
}
if(std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count() > 5000) //
{
printf(" **** NO Comm for 7 seconds ***** \n" );
iRecvError = 0;
ConnectedToServer = false;
disconnect();
onCommunication(false);
}
else
{
//printf(" recv time %s %d %d \n " ,(meNCUOption == NCU_FREE_AREA) ? "Local":"Remote",
// std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count(), (localClock_t::now() - LastRecvTime).count());
}
ScanReceivedData(); // scan and call the corresponding function
}
mpMainMutex->release();
}
}
Server Side Code
void CNosecapTCPIPServer::ServerInit(int port)
{
portno = port;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
if(listenfd < 0)
{
printf("ERROR opening socket \n");
}
optval = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
&optval , sizeof(int));
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons((unsigned short)portno);
if (bind(listenfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
{
m_errorCode = errno;
snprintf(m_errorMsg, 128, "%s", strerror(m_errorCode));
printf("ERROR on binding : %s \n", m_errorMsg );
}
printf("listen \n");
if (listen(listenfd, 5) < 0)
{
m_errorCode = errno;
snprintf(m_errorMsg, 128, "%s", strerror(m_errorCode));
printf("ERROR on listen %s \n", m_errorMsg);
}
clientlen = sizeof(clientaddr);
//fcntl(listenfd, F_SETFL, O_NONBLOCK);
}
void CNosecapTCPIPServer::TCP_HeartbeatThread()
{
while(1)
{
usleep(1000);
//takeMutex(50);
if(!ConnectedToClient)
{
//fcntl(listenfd, F_SETFL, O_NONBLOCK);
// accept: wait for a connection request
connfd = accept(listenfd, (struct sockaddr *) &clientaddr, &clientlen);
if (connfd < 0)
{
}
else
{
lockMutex();
//fcntl(connfd, F_SETFL, O_NONBLOCK); // blocking mode
ConnectedToClient = true;
LastRecvTime = localClock_t::now();
printCurenttime();
sprintf(printBuf, "Server established connection (log) \n ");
onLogMessage(printBuf);
unlockMutex();
}
}
else if(ConnectedToClient)
{
//// accept: wait for a connection request
if(connfd > 0)
{
strcpy((char*)buf,"");
n = recv(connfd, buf, ***5000***,0 ); // used recv instead of read.
//printf("recv connfd %d n = %d errno = %d \n", connfd, n, errno);
if (n <= 0)
{
if( n < 0 && errno != 11)
{
//disconnect();
//continue;
sprintf(printBuf, "Read Error n (%d) socket (%d) error (%d)\n",n, connfd , errno);
onLogMessage(printBuf);
}
if(n == 0)
{
//LastRecvTime = localClock_t::now();
}
}
else
{
lockMutex();
LastRecvTime = localClock_t::now();
ServerRxChar(buf, n); // Update to the serialNessageQ
SendECUCommand(msgSetTimerHeartbeat,MSG_NONE, (unsigned char*)buf+8, 1);
if(commState == false)
{
updateCommunicationStatus(true);
}
unlockMutex();
}
}
}
//unlockMutex();
}
}
void CNosecapTCPIPServer::TCP_BufferHandleThread()
{
while(1)
{
takeMutex(30);
ScanReceivedData(); // scan and call the corresponding function
if(ConnectedToClient)
{
if(std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count() > 8000) //
{
sprintf(printBuf, " \t\t (1) Not Reveived more than 10 secs : %d (%d) \n", (localClock_t::now() - LastRecvTime).count(),
std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count());
onLogMessage(printBuf);
LastRecvTime = localClock_t::now();
if(setTimeCommand == false)
disconnect();
}
else
{
//printf("\t\t (1)last recv %d (%d) \n",std::chrono::duration_cast<std::chrono::milliseconds>(localClock_t::now() - LastRecvTime).count(),
// (localClock_t::now() - LastRecvTime).count());
if(setTimeCommand)
setTimeCommand = false;
}
}
unlockMutex();
usleep(1000);
}
}
bool CNosecapTCPIPServer::SendCommand(void *pucCommand, int iLength)
{
int n;
unsigned char tp[200];
memcpy(tp, pucCommand, 200);
if(connfd)
{
n = write(connfd, pucCommand, iLength);
if (n < 0)
{
printf(" ERROR writing to socket (%d) error (%d) \n", connfd , errno);
sprintf(printBuf , " ERROR writing to socket (%d) error (%d) \n", connfd , errno);
onLogMessage(printBuf);
//disconnect();
//continue;
}
}
return true;
}