TCP sendto(C ++)在Linux上失败但在OSX上失败。 Errno:EINVAL 22参数无效

时间:2015-03-06 22:11:28

标签: linux macos c++11 tcp sendto

在我的应用程序的客户端,以下在OSX上正常运行。但是当在Linux(Ubuntu 12或Raspbian)上编译/运行时,sendto()始终会失败,并带有EINVAL / 22 / invalid参数。如何在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);
}

我怀疑Linux上的C ++ 11库和std :: vectors。我的makefile看起来与此类似。

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  

2 个答案:

答案 0 :(得分:1)

man 3 sendto表示如果&#34; EINVAL参数不是地址系列的有效长度&#34;则可能会返回dest_len,也许尽管该地址已经存在连接模式套接字忽略参数。鉴于您在标题中提到TCP,我假设control_fd是连接模式套接字。尝试使用send(control_fd, sendBytes, sendSize, 0)甚至write(control_fd, sendBytes, SendSize)代替。

答案 1 :(得分:0)

还有不足以继续下去。添加print语句以显示传递给sendto的所有参数的值。然后在转换回sockaddr_in后打印出res-&gt; ai_addr的相关成员。

一个假设。假设ipv4,ai_addrlen的值应完全等于sizeof(struct sockaddr_in)。如果套接字是ipv6,则为sizeof(sockaddr_in6)。如果传入的值大于该套接字类型的实际大小,则某些操作系统不太宽容。将ai_addrlen指定为sizeof(sockaddr_storage)就是这种情况。