LibVNC / libvncserver

LibVNCServer/LibVNCClient are cross-platform C libraries that allow you to easily implement VNC server or client functionality in your program.
GNU General Public License v2.0
1.1k stars 482 forks source link

Wait for message Function error Codes #486

Closed noorhaq closed 2 years ago

noorhaq commented 2 years ago

Hi, I just got a query on

int WaitForMessage(rfbClient* client,unsigned int usecs)
 {
   fd_set fds;
   struct timeval timeout;
   int num;

   if (client->serverPort==-1)
     /* playing back vncrec file */
     return 1;

   timeout.tv_sec=(usecs/1000000);
   timeout.tv_usec=(usecs%1000000);

   FD_ZERO(&fds);
   FD_SET(client->sock,&fds);

   num=select(client->sock+1, &fds, NULL, NULL, &timeout);
   if(num<0) {
 #ifdef WIN32
     errno=WSAGetLastError();
 #endif
     rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno));
   }

   return num;
 }

In this when the server is disconnected like not available anymore due to network disconnect, what would be the error message. In this what I did was using some references, if

int num = WaitFormessage(...);
if(num <0)
 return Error; //Like any error msg with error code
else
return 1; //And read the frame.

But the issue is when the VNC server disconnects like not a proper disconnect just disconnects due to network error. I don't get a error. But instead it keeps the last shown screen alive. And afterwards when the server reconnects to network it shows the disconnect message. And then attempt a new connection. So just need a little help here. As to what WaitForMessage returns if server doesn't respond in set time.

bk138 commented 2 years ago

I'd say in case of a network error in terms of unplugged cable you run into a timeout after a while and the function returns -1. Can you repro with some of the examples, e.g. https://github.com/LibVNC/libvncserver/blob/master/client_examples/SDLvncviewer.c?

noorhaq commented 2 years ago

Okay so let me explain my logic.

    while (client->state == CLIENT_CONNECTED) {
        /* Wait for start of frame */
        int wait_result = wait_for_messages(rfb_client,
                TIMEOUT);
        if (wait_result > 0) {
            /* Read server messages until frame is built */
            do {
                int frame_remaining;
                /* Handle any message received */
                if (!HandleRFBServerMessage(rfb_client)) {
                    // Clean Client.
                    break;
                }

                /* Increase the duration of this frame if client is lagging */
                if (required_wait > TIMEOUT)
                    wait_result = wait_for_messages(rfb_client,
                            required_wait*1000);

                /* Wait again if frame remaining */
                else if (frame_remaining > 0)
                   Wait for frame
                else
                    break;

            } while (wait_result > 0);

            /* Record end of frame, excluding server-side rendering time (we
             * assume server-side rendering time will be consistent between any
             * two subsequent frames, and that this time should thus be
             * excluded from the required wait period of the next frame). */
            last_frame_end = frame_start;

        }

        /* If an error occurs, log it and fail */
        if (wait_result < 0)
            // "Connection closed."

        /* Flush frame */
      Close Client
    }

Okay so this is the almost the skeleton code I put into my project using libvnc, removed all redundant parts. Now in it the issue.

When the VNC server disconnects due to network error it keeps the last shown screen on the Client side. But when the client reconnects even after 5s or say 5 mins it doesn't matter at that time it shows Server disconnected, reconnecting and reconnects via a new connection sequence. This is what I am not able to understand why. I have used the examples as reference but I am stuck.

bk138 commented 2 years ago

wait_for_messages() looks like it's not part of LibVNCClient - can you repro with the SDLvncviewer sample or even better: send a link to the code exposing your issue?

noorhaq commented 2 years ago

Okay so I checked. And the WaitForMessage doesn't return -1 on the server disconnection. When the server is disconnected and I call it it keeps on returning 0.

noorhaq commented 2 years ago

Same with the example like reproduce it. Checked the i by printing it in log.

noorhaq commented 2 years ago

I am thinking of adding a ping, like ping a message to server. To check if it connected or not.

bk138 commented 2 years ago

Okay so I checked. And the WaitForMessage doesn't return -1 on the server disconnection. When the server is disconnected and I call it it keeps on returning 0.

That's just the way it is on most platforms, see https://stackoverflow.com/questions/283375/detecting-tcp-client-disconnect for instance...