-1

I am new in Socket Programming. I am trying to create a client application. The server is a camera which communicates using TCP. The camera is sending continuous data. Using Wireshark, I can see that the camera is sending continuous packets of different sizes, but not more than 1514 bytes. But my recv function is always returning 2000 which is the size of my buffer.

unsigned char buf[2000];
int bytesIn = recv(sock, (char*)buf, sizeof(buf) , 0);
if (bytesIn > 0)
{
    std::cout << bytesIn << std::endl;
}

The first packet I receive is of size 9 bytes, which recv returns correct, but after that it always returns 2000.

Can anyone please tell me the solution so that I can get the correct size of the actual data payload?

EDIT

int bytesIn = recv(sock, (char*)buf, sizeof(buf) , 0);
if (bytesIn > 0)
{
    while (bytes != 1514)
    {
        if (count == 221184)
        {
            break;
        }
        buffer[count++] = buf[bytes++];
    }
    std::cout << count;
}

EDIT:

Here is my Wireshark capture:

WireShark Image

My Code to handle packets

int bytesIn = recv(sock, (char*)&buf, sizeof(buf) , 0);
        if (bytesIn > 0)
        {
            if (flag1 == true)
            {
                while ((bytes != 1460 && (buf[bytes] != 0)) && _fillFlag)
                {
                    buffer[fill++] = buf[bytes++];

                    if (fill == 221184)
                    {
                        flag1 = false;
                        _fillFlag = false;
                        fill = 0;
                        queue.Enqueue(buffer, sizeof(buffer));
                        break;
                    }
                }
            }
            if ((strncmp(buf, _string2, 10) == 0))
            {
                flag1 = true;
            }
        }

For each frame camera is sending 221184 bytes and after each frame it sends a packet of data 9 bytes which I used to compare this 9 bytes are constant.

This 221184 bytes send by camera doesn't have 0 so I use this condition in while loop. This code is working and showing the frame but after few frame it shows fully black frame. I think the mistake is in receiving the packet.

Lucky
  • 49
  • 7
  • 2
    TCP/IP is a stream not a packet protocol. On the network you see packets of data but at the API level the received data is a continuous stream of bytes. You need to parse these bytes to separate and/or join the received data back into the camera frames. – Richard Critten Jul 10 '18 at 08:54
  • I am putting that data into the buffer – Lucky Jul 10 '18 at 08:59
  • If the **Camera** sends successive data **without any specific distinction**, the client receives the buffer **indiscriminately**. The main reason is that the `recv` function only performs the simple function of reading the buffer set in your PC. – AleXelton Jul 10 '18 at 09:08
  • @Lakshraj Could you please post more about your implementation. What is the `221184`? Is it the `Maximum of Data` or `Size of per frame`? – AleXelton Jul 10 '18 at 09:11
  • the frame size if 288 x 384 I am receiving 221184 bytes per frame and I have to add 2 bytes to create a 16 bit image. The maxmimum size sended by camera is of size 1514 – Lucky Jul 10 '18 at 09:14
  • I am adding 2 bytes using shift operator – Lucky Jul 10 '18 at 09:15
  • @Lakshraj I think you didn't express your problem well. You mean that the Camera is sending 1514 bytes(fixed) buffer to client continuously, and per frame size is 221184(fixed) bytes. Then you want receive buffer continuously and make image-s using buffer, right? If it is I will help you. – AleXelton Jul 10 '18 at 09:18
  • No need to cast `buf` to `char*`. – Maxim Egorushkin Jul 10 '18 at 09:46
  • @Lakshraj Please see my answer. You can use this function to make frame. – AleXelton Jul 10 '18 at 09:56
  • 1
    You have to actually implement the message protocol the camera is using. TCP is not a message protocol. – David Schwartz Jul 11 '18 at 07:54
  • but camera is using TCP – Lucky Jul 11 '18 at 08:11
  • @Lakshraj The camera is using TCP to send messages. You need to implement whatever protocol it is using to do that. Protocols exist in layers. Below TCP is IP. Below that might be Ethernet or WiFi or something. Above TCP, in this case, is some kind of message protocol that is being used by the camera. You need to implement that message protocol on top of TCP just as the camera did. – David Schwartz Jul 12 '18 at 07:17
  • @Lakshraj the Wireshark screenshot you provided clearly shows that you are dealing with [RTSP](https://en.m.wikipedia.org/wiki/Real_Time_Streaming_Protocol) packets. RTSP messages are sent over TCP, and associated streaming media is *typically* sent over UDP using [RTP](https://en.m.wikipedia.org/wiki/Real-time_Transport_Protocol), but can also be sent over TCP instead. Both RTSP and RTP are quite involved, they are not for the feint of heart to tackle, and certainly not for beginners. You are best off finding a good RTSP/RTP library to handle the details for you. – Remy Lebeau Jul 12 '18 at 07:22
  • I don't know much about how to implement a protocol camera is using. I am receiving the byte packets. The data payload that I am receiving may vary between 100 - 1460, but the problem is when I receive that in buf if the size is less that 1460 it fills the buffer with 0 which results in some black portions in my image. I am editing the question and providing the code that work with bytes. – Lucky Jul 12 '18 at 09:02

2 Answers2

1

The first packet I receive is of size 9 bytes which it print correct after that it always print 2000. So can anyone please tell me the solution that I only get the size of actual data payload.

TCP is no packet-oriented, but a stream-oriented transport protocol. There is no notion of packets in TCP (apart maybe from a MTU). If you want to work in packets, you have to either use UDP (which is in fact packet-oriented, but by default not reliable concerning order, discarding and alike) or you have to implement your packet logic in TCP, i.e. reading from a stream and partition the data into logical packets once received.

Jodocus
  • 7,493
  • 1
  • 29
  • 45
  • Sir I am receiving 221184 bytes for one frame, which comes in chunks so how can I implement that – Lucky Jul 10 '18 at 08:55
  • @Lakshraj The bytes you are receiving are from multiple frames (and probably a last part frame). You need to parse the bytes to recreate the original frames. And add any remaining bytes to the beginning of the next data to be received. – Richard Critten Jul 10 '18 at 09:03
  • I am doing the same but when I print the buf using while loop it is printing ffffffcc – Lucky Jul 10 '18 at 09:12
  • @Lakshraj TCP is a byte stream. The camera MUST frame its data in such a way that you can then know where one message ends and the next begins. Your reading code MUST account for that framing. There are only 3 ways a message can be framed in TCP: 1) fixed-sized messages; you can read N number of bytes at a time. 2) prefixing a message with its size; you can read the size value first, then read the specified number of bytes that follow. 3) using a unique delimiter between messages. You can read bytes until you encounter the delimiter. – Remy Lebeau Jul 10 '18 at 18:29
  • @Lakshraj Which way is your camera framing its data exactly? The details of the camera's TCP implementation should be in the camera's documentation (what type of camera are you using exactly?). Otherwise, what exactly does Wireshark show for the TCP payloads of the first few packets received? – Remy Lebeau Jul 10 '18 at 18:33
  • @RemyLebeau Sir The camera is sending packets of different byte length. but not more than 1514. When I try to print the buffer after original bytes it shows cc so can you please provide me the solution – Lucky Jul 11 '18 at 04:29
  • @Lakshraj **variable**-length data MUST be framed using #2 or #3 as I described. Without seeing the actual data, such as in a Wireshark capture, there is no way to tell you the *proper* way to read it. So again, what kind of camera are you working with exactly, and HOW does it frame its data? If you can't answer that, you can't progress forward in your project. What you have described so far is making *assumptions* you simply can't make in this situation. You need to *know* what is actually happening – Remy Lebeau Jul 11 '18 at 06:04
  • @RemyLebeau Sir, I got the solution for the problem but it their any way through which I can find the original size of bytes received through recv function like when using UDP sockets recvfrom function gives the original size of bytes received. – Lucky Jul 12 '18 at 06:40
  • @Lakshraj You have to actually implement the message protocol that the camera is using. Otherwise, your code will have no idea what a "message" is. TCP doesn't have application-level messages so systems that require them and use TCP have to implement some kind of message protocol on top of TCP. Your camera clearly does that, since it sends messages using TCP. You have to too. – David Schwartz Jul 12 '18 at 07:19
  • @Lakshraj that is not how TCP works. UDP is message-oriented, the number of sent bytes is in the transmitted datagram. But TCP is stream-oriented, there is no 1:1 relationship between sends and reads. As David Schwartz mentioned, TCP-based protocols require extra messaging structure, and you must follow that structure. In this case, your Wireshark screenshot clearly shows that the structure is the [RTSP](https://en.m.wikipedia.org/wiki/Real_Time_Streaming_Protocol) protocol, which runs on top of TCP. – Remy Lebeau Jul 12 '18 at 07:28
1
Size of per frame is : 221184 (fixed)   
Size of per recv is : 0 ~ 1514

My implementation here :

DWORD MakeFrame(int socket)
{
    INT nFrameSize = 221184;
    INT nSizeToRecv = 221184;
    INT nRecvSize = 2000;
    INT nReceived = 0;
    INT nTotalReceived = 0;
    BYTE byCamera[2000] = { 0 };    // byCamera size = nRecvSize
    BYTE byFrame[221184] = { 0 };   // byFrame size = nFrameSize

    while(0 != nSizeToRecv)
    {
        nRecvSize = min(2000, nSizeToRecv);
        nReceived = recv(socket, (char*)byCamera, nRecvSize, 0);

        memcpy_s(byFrame + nTotalReceived, nFrameSize, byCamera, nReceived);

        nSizeToRecv -= nReceived;
        nTotalReceived += nReceived;
    }

    // byFrame is ready to use.
    // ...
    // ...

    return WSAGetLastError();
}

enter image description here

AleXelton
  • 767
  • 5
  • 27