thomas_haximus
thomas_haximus

Reputation: 1531

TCP/Ip network communication in c++

I am trying to write a threaded function that sends system information via Tcp/ip over the local network to another computer. I have been using sockets to achieve this and this has worked out quite allright thus far. But I am now at a point where this usually works but around 30% of the time I get error messages telling me that the socket can not be opened. I use the activeSocket library for the sockets.

#include "tbb/tick_count.h"
#include "ActiveSocket.h"

using namespace std;

CActiveSocket socket;
extern int hardwareStatus;



int establishTCP() {
 char time[11];
 int communicationFailed = 0;
 memset(&time, 0, 11);
 socket.Initialize();
 socket.SetConnectTimeout(0, 20);
 socket.SetSendTimeout(0, 20);
 return communicationFailed;
}


int monitor() {
 cout << "Monitor: init continious monitoring" << endl;
 int communicationFailed;
 tbb::tick_count monitorCounter = tbb::tick_count::now();
 while (!closeProgram) {
  tbb::tick_count currentTick = tbb::tick_count::now();
  tbb::tick_count::interval_t interval;
  interval = currentTick - monitorCounter;
  if (interval.seconds() > 2) {
   monitorCounter = tbb::tick_count::now();
   communicationFailed = 1;
   char buffer[256];
   sprintf(buffer, "%d;", hardwareStatus);

   establishTCP();

   char *charip = new char[monitoringIP.size() + 1];
   charip[monitoringIP.size()] = 0;
   memcpy(charip, monitoringIP.c_str(), monitoringIP.size());
   const uint8* realip = (const uint8 *) charip;
   int monitorCount = 0;
   cout << "Monitor: " << buffer << endl;
   while (communicationFailed == 1 && monitorCount < 2) {
    monitorCount++;
    if (socket.Open(realip, 2417)) {
     if (socket.Send((const uint8 *) buffer, strlen(buffer))) {
      cout << "Monitor: Succeeded sending data" << endl;
      communicationFailed = 0;
      socket.Close();
      } else {
       socket.Close();
       communicationFailed = 1;
       cout << "Monitor: FAILED TO SEND DATA" << endl;
      }
     } else {
       socket.Close();
       communicationFailed = 1;
       cout << "Monitor: FAILED TO OPEN SOCKET FOR DATA" << endl;
      }
     }
    if (monitorCount == 2) cout << "Monitor: UNABLE TO SEND DATA" << endl;
   }
  }
  return communicationFailed;
 }

I think I am doing something wrong with these functions and that the problem is not on the other side of the line where this data is received. Can anyone see any obvious mistakes in this code that could cause the failure? I keep getting my own cout message "Monitor: FAILED TO OPEN SOCKET FOR DATA"

EDIT: With telnet everything works fine, 100% of the time

Upvotes: 0

Views: 3283

Answers (3)

thomas_haximus
thomas_haximus

Reputation: 1531

I eventually found out the problem with my code. As the connection was unstable and working for 70% of the time it seemed to be a timeout issue. I removed the two timeout settings

socket.SetConnectTimeout(0, 20);
socket.SetSendTimeout(0, 20);

Now it works perfectly fine, thanks for the troubleshooting tips though!

Upvotes: 0

Robᵩ
Robᵩ

Reputation: 168626

socket is a global variable. It might be re-used concurrently between two threads or sequentially inside one thread. In fact, the while(~closeProgram) loop indicates that you intend to use it sequentially.

Some documentation for CActiveSocket::Open reads: "Connection-based protocol sockets (CSocket::SocketTypeTcp) may successfully call Open() only once..."

Perhaps your program fails when you call .Open() twice on the same object.

Upvotes: 0

Ed Heal
Ed Heal

Reputation: 59997

You can use netstat to check that the server is listening on the port and connections are being established. Snoop is another good application in your Armour for finding out what is going wrong. Another possibility is to use telnet to see if the client can connect to that IP address and port. As to the code I will take a look at it later to see if something has gone awry.

Upvotes: 1

Related Questions