Kam*_*aze 2 c sockets linux linaro
好的,首先是下面的代码:
int recvMast_sock;
struct sockaddr_in serv_addr, cli_addr;
socklen_t cli_len;
if ((recvMast_sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
critErr("listen:socket=");
}
fillSockaddrAny(&serv_addr, UDP_NODE_LISTEN_PORT);// fills the sockaddr_in works fine elsewhere
if ((bind(recvMast_sock, (struct sockaddr*) &serv_addr, sizeof serv_addr)) < 0)
{
critErr("listen:bind recv_mast_sock:");
}
recvReturn_i = recvfrom(recvMast_sock, &recvBuff[0], (size_t)1, 0, (struct sockaddr*) &cli_addr, &cli_len);
if(recvReturn_i <0)
printf("recv error%d\n",errno);
Run Code Online (Sandbox Code Playgroud)
critErr是处理错误的函数,还包括错误的打印和exit。
如果有关联,它将在线程中运行。如果我在具有ARM Cortex A9和Linaro Linux(基于精确Ubuntu)的Zedboard(ZYNQ-7000 SoC)上编译并运行它。它显示错误,22但仍具有的接收值recvBuff[0]。
使用xubuntu在我的VM中运行它可以正常工作。
错误22等于EINVAL被描述为无效参数。
在recvfrom(2)它的手册页中,状态EINVAL表示MSG_OOB已设置标志,但我不使用任何标志(传递0)。
在星期五休假之前,我开始apt-get升级,因为我希望它是一个有缺陷的库或类似的东西。我可以在周一检查回来,但是也许有人在这里有另外一个主意。
您需要先进行初始化,cli_len然后再将其传递给recvfrom():
cli_len = sizeof(cli_addr);
Run Code Online (Sandbox Code Playgroud)
您没有初始化它,因此它具有随机值。如果该值恰好是< sizeof(cli_addr),则recvfrom()可能失败EINVAL,或至少截断该地址,因为它认为cli_addr该大小不足以接收客户端地址。如果该值远大于sizeof(cli_addr),则recvfrom()可能会认为缓冲区超出了有效内存范围。
你必须告诉recvfrom()多么大的cli_addr实际上是。文档中明确指出:
参数addrlen是一个值结果参数,调用方应在调用与src_addr相关联的缓冲区大小之前对其进行初始化,并在返回时进行修改以指示源地址的实际大小。如果提供的缓冲区太小,返回的地址将被截断。在这种情况下,addrlen将返回一个大于提供给调用的值。
因此,您必须在调用之前cli_len使用的总大小进行初始化,然后使用实际写入的地址的大小进行更新。 可以大于地址,例如,当使用一种结构在双堆栈套接字上接受IPv4或IPv6地址时。在问题的示例中,正在使用IPv4套接字,因此必须将其初始化为值> = 。cli_addrrecvfrom()recvfrom()cli_lencli_addrcli_addrsockaddr_storagecli_lensizeof(sockaddr_in)
| 归档时间: |
|
| 查看次数: |
2294 次 |
| 最近记录: |