0

I am using Winsock2 sockets to transfer some data over UDP. I am having difficulties passing the array into the sendTo() function to send the data.

I have wrote a mySocket class for future reuse and I have the following method currently, which works.

bool MySocket::sendData()
{
short int values[] = {1000,2000,3000,4000,5000};
int ret = sendto( sd,(const char*)values, sizeof(values) , 0, (sockaddr *)&sin, sizeof(sin) );
if(ret == SOCKET_ERROR)
{
    return false;
}
return true;
}

Now I want to pass in a array instead of having

short int values[] = {1000,2000,3000,4000,5000};

So the new function would look like:

bool MySocket::sendData(short int data[])
{
     short int * values = data;
int ret = sendto( sd,(const char*)&values, sizeof(data) , 0, (sockaddr *)&sin, sizeof(sin) );
if(ret == SOCKET_ERROR)
{
    return false;
}
return true;
}

When the function is called the call would be:

short int data[] = {1000,2000,3000,4000,5000}; //Or some other pre-assembled list of short ints
if(socket->sendData(data))
    cout << "Server: Packet Sent" << endl;
else
    cout << "Server_Error: Packet failed to send" << endl;

I seem to just be getting the address of the pointer for data or values. I have been playing around with the "&" and pointers, but haven't found the correct way to transfer anything but the first number, which is where the pointer is pointing. I mostly write code in C# and switching back to C++ now has left my pointer skills pretty rusty.

How would I pass or use the passed in array to send it correctly?

Brandon
  • 191
  • 2
  • 15
  • `short int * values = data` why do this? why not use `data` directly? – Tim Jan 07 '13 at 19:46
  • ok, I'm getting 1000, and 2000 using data directly instead of assigning to a pointer. – Brandon Jan 07 '13 at 19:51
  • which is because your `sizeof(data)` is the size of a pointer, which is twice as big as a short. see my answer for how to fix this, and a more detailed explanation. – s.bandara Jan 07 '13 at 19:53

2 Answers2

2

What MySocket::sendData is getting should be a pointer to the data, not the address of the pointer. sizeof will not be the right way to check for the number of elements. Indeed, that will be the sizeof a pointer as you are saying. Also, you should be passing (const char *)values to sendto. That will do. To calculate the number of bytes to send, multiply the number of elements by sizeof(short). So I would suggest you pass the number of elements as an additional argument to MySocket::sendData. It will look like this:

bool MySocket::sendData(short int data[], int n_data)
{
    int ret = sendto(sd, (const char*)values, n_data * sizeof(short) , 0, (sockaddr *)& sin, sizeof(sin));
    if(ret == SOCKET_ERROR)
    {
        return false;
    }
    return true;
}
s.bandara
  • 5,636
  • 1
  • 21
  • 36
1

You need to explicitly pass size of the data array to your sending function. This is one of the subtleties of C and C++ - array type is decayed to a pointer when passed as function argument, so you lose array size information. Just do something like this:

bool sendInts( short* data, size_t count ) {
    int rc = ::send( data, count * sizeof( short ), ... );
    // handle errors etc.
}

Or even better, take an std::vector<short> by reference:

bool sendInts( const std::vector<short>& data ) {
    assert( data.size() > 0 );
    int rc = ::send( &data[0], data.size() * sizeof( short ), ... );
    // handle errors etc.
}
Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171