c++socketscameraudppackets

recvfrom only receive few packets after that it goes in waiting state


Hi I am new in Socket Programming and try to create a client server applciation using in which my server is Camera and client in my C++ application. When I see the packet transfer between computer and camera it showing that camera is sending more than 150000 packets after that it stops. But when I am receving that I am able to receive 400 - 450 packets at a time after that the recvfrom function goes to waiting state. and If I again run that exe file without stopping the previous one it again receive 400-450 packets.

Code for Receving Packets

SOCKET out1 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    if (out1 == INVALID_SOCKET)
    {
        cout << out1 << endl;
    }
    server.sin_family = AF_INET;
    server.sin_port = htons(3956);
    inet_pton(AF_INET, "192.168.1.140", &server.sin_addr);
    int serverLength = sizeof(server);

    connect(out1, (sockaddr*)&server, serverLength);
    while (1)
    {
        memset(buf, 0, sizeof(buf));
        int bytesIn = recvfrom(out1, buf, 1444, 0, (sockaddr*)&server, &serverLength);
        if (bytesIn > 0)
        {
            cout << "Image Received :" << bytesIn <<packet_counter << endl;
            packet_counter++;
        }
        else
        {
            cout << "Not Received : " << endl;
        }
    }

I am running the .exe with the administrator rights.

So can anyone please tell me why the recvfrom function is going in waiting state.

Thanks in Advance.

EDIT:-

Sorry that I am providing the whole code.

  #include <stdio.h>
#include <Windows.h>
#include <thread>
#include <WinSock2.h>

// Library
#pragma comment(lib, "ws2_32.lib")

using namespace std;

//***** Function Decleration *****//
void _packetConfig(SOCKET);
void _sendPacket(SOCKET, const char*, int, int);

// Global Variable
sockaddr_in server;

//***** Main Function *****//
void main(char argc, char* argv[])
{
    WSADATA data;
    WORD version = MAKEWORD(2, 2);
    if(WSAStartup(version, &data) == SOCKET_ERROR)
    {
        cout << "Can't Start Socket" << WSAGetLastError<<endl;
        return;
    }
    char buf[2000];

        SOCKET out1 = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
        if (out1 == INVALID_SOCKET)
        {
            cout << out1 << endl;
        }
        server.sin_family = AF_INET;
        server.sin_port = htons(3956);
        inet_pton(AF_INET, "192.168.1.140", &server.sin_addr);
        int serverLength = sizeof(server);

        connect(out1, (sockaddr*)&server, serverLength);


        int packet_counter = 0;


        SOCKET out = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

        _packetConfig(out);

        cout << "Inside Main" << endl;
        while (1)
        {
            //connect(out1, (sockaddr*)&server, serverLength);
            memset(buf, 0, sizeof(buf));
            int bytesIn = recvfrom(out1, buf, 1444, 0, (sockaddr*)&server, &serverLength);
            if (bytesIn > 0)
            {
                cout << "Image Received :" << bytesIn <<packet_counter << endl;
                packet_counter++;
            }
            else
            {
                cout << "Not Received : " << endl;
            }
        }

        WSACleanup();
}

//***** Function to Send Bytes to the Camera *****//
void _sendPacket(SOCKET sock, const char* s, int len, int i)
{
    int sendOk = sendto(sock, (const char*)s, len, 0, (sockaddr*)&server, sizeof(server));

    if (sendOk == SOCKET_ERROR)
    {
        cout << "Didn't Work" << WSAGetLastError() << endl;
    }
    else
    {
        cout << "\nSend Succesfully" << " " << i << endl;
    }
    char buf[2000];
    int serverLength = sizeof(server);
    int bytesIn = recvfrom(sock, buf, 2000, 0, (sockaddr*)&server, &serverLength);
    if (bytesIn > 0)
    {
        cout << "Message Received :" << bytesIn << endl;
    }
}

//***** Function to call the _sendPacket function and send commands to the Camera *****//
void _packetConfig(SOCKET sock)
{
    // 59 Commands and every command call _snedPacket function to send commands to camera  it will working properly
}

In the above code I have to first send this 59 commands written in _packetConfig function then only camera will send Image packets I am receiving the reply of all that commands.

When I run wireshark also with that code I can see that after these 59 commands the camera is giving 3580*51 packets.i.e 51 frames and each frame contain 3580 packets


Solution

  • Thank you for posting your code. There are actually a few things wrong with it so first I will post some code that works as a reference and then mention the major issues I noticed with yours afterwards.

    OK, here is some code that works for me:

    #include <WinSock2.h>                   // ** before** windows.h
    #include <WS2tcpip.h>
    #include <iostream>
    #include <stdio.h>
    #include <Windows.h>
    #include <assert.h>
    
    #pragma comment (lib, "ws2_32.lib")
    
    const int port = 3956;
    
    // main
    int main (char argc, char* argv[])
    {
        WSADATA wsadata;
        WORD version = MAKEWORD(2, 2);
    
        int err = WSAStartup (MAKEWORD (2, 2), &wsadata);
        if (err)
        {
            std::cout << "WSAStartup failed, error: " << err << std::endl;
            return 255;
        }
    
        char buf [1444];
        bool send = argc > 1 && _stricmp (argv [1], "send") == 0;
    
        if (send)
        {
            // Send
            SOCKET skt_out = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
            assert (skt_out != INVALID_SOCKET);
    
            sockaddr_in destination_address = { };
            destination_address.sin_family = AF_INET;
            destination_address.sin_port = htons (port);
            inet_pton (AF_INET, "192.168.1.2", &destination_address.sin_addr);
            memset (buf, 'Q', sizeof (buf));
            printf ("Sending: ");
    
            for ( ; ; )
            {
                sendto (skt_out, buf, sizeof (buf), 0, (const sockaddr *) &destination_address, sizeof (destination_address));
                printf (".");
                Sleep (50);
            }
    
            closesocket (skt_out);
            WSACleanup ();
            return 0;
        }
    
        // Receive
        SOCKET skt_in = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        assert (skt_in != INVALID_SOCKET);
    
        int receive_buffer_size = 65536;
        if ((setsockopt (skt_in, SOL_SOCKET, SO_RCVBUF, (const char *) &receive_buffer_size, sizeof (int)) ) < 0)
            std::cout << "Could not set SO_RCVBUF, error: " << WSAGetLastError () << std::endl;
    
        sockaddr_in receive_address = { };
        receive_address.sin_family = AF_INET;
        receive_address.sin_port = htons (port);
        receive_address.sin_addr.s_addr = htonl (INADDR_ANY);
    
        if (bind (skt_in, (const sockaddr *) &receive_address, sizeof (receive_address)) == -1)
        {
            std::cout << "bind failed , error: " << WSAGetLastError () << std::endl;
            return 255;
        }
    
        int packetCounter = 0;
        printf ("Receiving: ");
    
        for ( ; ; )
        {
            int bytesIn = recvfrom (skt_in, buf, sizeof (buf), 0, NULL, 0);
            if (bytesIn > 0)
                std::cout << "Packet received:" << bytesIn << " bytes (" << ++packetCounter << ")" << std::endl;
            else
                std::cout << "Receive error: " << WSAGetLastError () << std::endl;
        }
    
        closesocket (skt_in);
        WSACleanup ();
        return 0;
    }
    

    To run this in 'send' mode, specify send as the first argument on the command line. Otherwise it acts as a receiver (aka server).

    So what's wrong with your code? Well, in no particular order:

    But having said all that, it was essentially the call to bind that you were missing. I rewrote the code because yours is rather messy.

    Also, important detail, UDP doesn't guarantee delivery - there are a number of reasons why a packet that has been sent does not get received or might even get received out of sequence (does your camera sequence the packets in some way?)
    You need to cater for that in the logic of your application (and it that's a problem, it's better to use TCP, which does guarantee packet delivery and sequencing).