Search code examples
linuxmacosc++11tcpsendto

TCP sendto (C++) fails on Linux but not OSX. Errno: EINVAL 22 Invalid argument


On the client side of my application, the following runs fine on OSX. But when compiled/run on Linux (Ubuntu 12 or Raspbian) sendto() always fails with a EINVAL/22/invalid argument. How do I run it on Linux?

std::vector<uint8_t> rawVect;
// rawVect.push_back()...a bunch of bytes

const uint8_t* sendBytes = &rawVect[0]; // or rawVect.data();  
size_t sendSize = rawVect.size();

if(sendSize > 0){

    long numBytes = sendto(control_fd, sendBytes, sendSize, 0, res->ai_addr, _res->ai_addrlen);
}

I suspect C++ 11 libraries and std::vectors on Linux. My makefile looks similar to this.

mac:  
g++ -std=c++0x myprogram.cpp 
# (w/ llvm libc++)

ubuntu:  
clang++-3.5 -g -std=c++11 -stdlib=libc++ myprogram.cpp  
# couldn't use g++ 4.8 or prior because it didn't support std::vector::insert as I was using it elsewhere. 4.9 not avail for Ubuntu 12.  

pi:  
g++-4.9 -std=c++0x myprogram.cpp  

Solution

  • man 3 sendto says that EINVAL may be returned if "The dest_len argument is not a valid length for the address family", perhaps despite the fact that the address argument is ignored for connected-mode sockets. Given that you mention TCP in the title, I assume that control_fd is a connected-mode socket. Try simply using send(control_fd, sendBytes, sendSize, 0) or even write(control_fd, sendBytes, SendSize) instead.