我不太了解网络连接。我遵循了很多示例代码,它第一次有效,但第二次无效,这没有任何意义。
“服务器端”是运行 Ubuntu 16.04 的 PC。“客户端”在 TI DSP 上运行 LwIP。这是有效的代码部分:
/* find out who is out there */
usock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(!usock)
{
printf("can't create UDP socket \n");
exit(-4);
}
/* si_me is local receive port */
memset((char *) &si_me, 0, sizeof(si_other));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(RCVPORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
bind(usock, (struct sockaddr*)&si_me, slen);
/* si_other is broadcast receive port */
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(BRDCST);
inet_aton("192.168.1.255", &si_other.sin_addr);
setsockopt(usock, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
flags = fcntl(usock, F_GETFL);
flags |= O_NONBLOCK;
fcntl(usock, F_SETFL, flags);
[...]
printf("sending %s", sndbuffer);
if (sendto(usock, sndbuffer, 26, 0 , (struct sockaddr *) &si_other, slen) < 0)
{
printf("failed udp sendto\n");
exit(-5);
}
clock_gettime(CLOCK_REALTIME, &rtc);
ttime = rtc.tv_sec;
j = 0;
printf("waiting for response\n");
while((j <= 0) && (ttime + 10 > rtc.tv_sec))
{
j = recvfrom(usock, &rcvbuffer[numBytes], 256, 0, NULL, 0);
if(j > 0)
{
numBytes += j;
break;
}
clock_gettime(CLOCK_REALTIME, &rtc);
}
printf("got %ld bytes\n", numBytes);
rcvbuffer[24] = 0;
printf("received %s", rcvbuffer);
该块的目的是让客户端知道服务器所在的IP地址,因此服务器端知道谁在那里。它最终需要扩展以处理多个客户,但一步一步!
我尝试使用不同的套接字,然后尝试了第一次收到的同一个套接字,但同样的事情发生了。以下部分起作用:
/* far address from response */
memset((char *) &si_radar, 0, sizeof(si_radar));
si_radar.sin_family = AF_INET;
si_radar.sin_port = htons(LELYPORT);
inet_aton(&rcvbuffer[7], &si_radar.sin_addr);
printf("sending to: %s:%d\n", &rcvbuffer[7], LELYPORT);
sprintf(sndbuffer, " %02d:%02d:%06.3f %05d %02d:%02d:%06.3f\n",
shr, smn, seconds, i, ehr, emn, econ);
numBytes = sendto(usock, sndbuffer, 34, 0, (struct sockaddr*)&si_radar, slen);
printf("sent %s", sndbuffer);
然后当我打电话时什么也没有出现:
while((numBytes < 22) && (i < 10))
{
j = recvfrom(usock, rcvbuffer, 256, 0, NULL, 0);
if(j > 0) numBytes += j;
if(j < 0)
{
if(errno != EAGAIN)
perror("receive error:");
}
在此之后,我进行了时钟检查,并在 30 秒后尝试重新发送。在wireshark 上,我看到了sendto() 的传出消息以及LwIP/DSP 的响应。但是, recv() 永远不会得到任何响应!
我尝试使用不同的端口、不同的套接字、关闭第一个套接字并创建一个新的套接字,但它永远不会在第二个 UDP 上看到响应。
我假设有一些我没有看到的微不足道的东西,并且所有不同的尝试组合都绕过了它,而不是解决了问题。其中一些组合包括将 &si_radar、&rlen 放在 recvfrom() 中而不是 NULL、0 以及类似
rdrSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(!rdrSock)
{
printf("can't create UDP radar socket \n");
exit(-4);
}
/* local address fixed */
memset((char *) &si_me, 0, sizeof(si_other));
si_me.sin_family = AF_INET;
si_me.sin_port = htons(LELYPORT);
inet_aton("192.168.1.13", &si_me.sin_addr);
if(bind(rdrSock, (struct sockaddr*)&si_me, slen)<0) perror("bind failed");
flags = fcntl(rdrSock, F_GETFL);
flags |= O_NONBLOCK;
fcntl(rdrSock, F_SETFL, flags);
然后使用 rdrSock 代替 usock。没区别。
有谁知道为什么?UDP 应该只发送数据和获取数据,尤其是当它进入端口时!谢谢,迈克