0

I am using C, Linux, and a GIO GSocket to build a small application to communicate with a digital projector via TCP. The socket connects successfully and I am able to send messages to the projector successfully. My problem is that I am not able to receive the automated acknowledgement messages returned by the projector when it receives a command. When I send a message then use g_socket_receive, it blocks and never seems to receive a response.

My suspicion of the problem, based on past similar issues in other languages, is that when I send a message using g_socket_send the message is sent on a random available local port. The projector then automatically replies to the port the message originated from. Not knowing what port it used, I am unable to have my GSocket listen on the correct port. In other languages it's been a simple matter of manually setting my local outbound port so that I knew where the response would come back to. However I have not been able to find any information at all about how to do so with a GSocket.

Can anyone offer any assistance with this, or any thoughts on what else the problem could be that I'm missing?

Thanks!

DrRocket
  • 215
  • 2
  • 14
  • If you initiate the TCP connection to a server (your projector), the TCP/IP stack manages the local ports (you only need to know the server's IP:PORT pair) so you don't need to `listen` for anything; listen is for creating a server yourself. My guess is that your problem lies somewhere else... – Unknown Sep 23 '13 at 14:18

2 Answers2

0

You can bind an outbound GSocket to a local address (IP and port) with the g_socket_bind function, just like you do for listening sockets.

Doing that is unlikely to solve your problem though. The projector should send the reply packets to the port from which the request was sent; very rarely you need to bind the client socket to a particular port. Verify what is being sent and received with wireshark or tcpdump.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • So, if I have NOT bound my socket to a particular local port, when I call g_socket_receive() using the same socket on which I just called g_socket_send(), it should automatically check for incoming data on the same port number it sent the message out on? If this is the case then my problem must be elsewhere. I will try wireshark and see what I can see. – DrRocket Sep 23 '13 at 14:39
0

Your read/receive call most likely blocks because you order to read/receive more bytes than the answer sent is long.

For testing purpose do something like this:

int fd = -1;
/* setup fd */
char buffer[1024] = {0};
ssize_t size_buffer = sizeof(buffer) - 1;
size_t size_read_total = 0;
ssize_t size_read = 0;

while (size_buffer > size_read_total)
{
  size_read = read(fd, buffer + size_read_total, 1); /* Wait until exactly one byte had been read. */
  if (-1 = size_read)
  {
    if (EINTR == errno)
    {
      continue;
    }

    if ((EAGAIN == errno) || (EWOULDBLOCK == errno))
    {
      continue;
    }

    break;  /* Fatal error */
  }
  else (0 == size_read)
  {
    break; /* Connection closed by sending side. */
  }

  size_read_total += size_read;
} 

if (-1 == size_read)
{
  perror("read() failed");
}
else
{
  printf("Received %zd bytes as: '%s'\n", size_read_total, buffer);
}
alk
  • 69,737
  • 10
  • 105
  • 255
  • Where would I plug this in in relation to the g_socket_read call? To run after the blocking times out? – DrRocket Sep 23 '13 at 15:25