Search code examples
linuxtcpsocket

TCP Socket FIONREAD only increments on every recv call linux


I have a server client setup where when the server fd has data to read, a callback is run to format and propagate the data. The server and client share the same header defining the payload as follows:

#ifndef DATA_HEADER_
#define DATA_HEADER_

#pragma pack(1)

typedef struct {
  int command;
  uint8_t val;
} cmd_t;

#pragma pack()

#endif

The callback function that does the read is as follows:

int Server::onBytesAvailable(Socket *s)
{
  //get bytes available and set up data array
  int len = s->bytesAvailable();
  char *msg = new char[len];
  s->read(msg, len);

  //cast as command struct
  cmd_t *cmd = (cmd_t *) msg;

  //print values
  std::cout << "LEN: " << len << std::endl;
  std::cout << "MSG LEN " << sizeof(msg) << std::endl;
  std::cout << "CMD: " << cmd->cmdid << std::endl;
  std::cout << "VAL: " << cmd->togglePwr << std::endl;

  propigateData(cmd);
  return 0;
}

the bytesAvailable() call runs ioctl(fd, FIONREAD, &size) to get the bytes available for reading from the socket. Whenever the callback is run, bytesAvailable() just continues to increment by 5, and the value of the data in the payload is just garbage. The read call runs recv on the fd and puts the data in the msg array.

The printed output looks like the following:

output:

LEN: 5
MSG LEN 4
CMD: 0
VAL: ▒
LEN: 10
MSG LEN 4
CMD: 0
VAL: ▒
LEN: 15
MSG LEN 4
CMD: 0
VAL:
LEN: 20
MSG LEN 4
CMD: 0
VAL:

I am new with sockets so any help would be greatly appreciated!


Solution

  • Forgot to mark this as solved. All socket instances inherit their file descriptor vars from a socket base class. The TCPSocket class had an overloaded fd var that was getting set instead of the base fd.