udp socket同样的代码为什么Linux行,Vxworks就不行?(有码)
void usrAppInit (void)
{
#ifdefUSER_APPL_INIT
USER_APPL_INIT;/* for backwards compatibility */
#endif
/* add application specific code here */
int count, loopi, j;
BYTE node_id = sysProcNumGet();
END_OBJ * pEnd;
char ipaddr[40];
END_TBL_ENTRY* pDevTbl;
BYTE bMasterMacAddress[6];
BYTE byFpgaStatus;
DWORD dwNodeType;
int sockd;
struct sockaddr_in my_addr, srv_addr;
char buf[2048];
int addrlen;
/*网口初始化*/
if (mBlkInit() != OK)
{
printf("intercom_init: mBlkInit fail!\n");
}
/*set mac address and IP address*/
bMacAddress[0][5] = node_id;
bMacAddress[1][5] = node_id;
for (loopi = 0; loopi < 2; loopi++)
{
pRouteCookie[loopi] = NULL;
}
muxAddrResFuncAdd (M2_ifType_ethernet_csmacd, 0x800, arpresolve);
/* Add in mux ENDs. */
for (count = 0, pDevTbl = endDevTbl; pDevTbl->endLoadFunc != END_TBL_END;
pDevTbl++, count++)
{
if (!pDevTbl->processed)
{
pEnd = (END_OBJ *) muxDevLoad(pDevTbl->unit,
pDevTbl->endLoadFunc,
pDevTbl->endLoadString,
pDevTbl->endLoan, pDevTbl->pBSP);
if (pEnd == NULL)
{
printf("muxDevLoad failed for device entry %d!\n", count);
}
}
}
for (loopi = 0; loopi < count; loopi++)
{
pEnd = endFindByName("lnPci", loopi);
pRouteCookie[loopi] = muxBind("lnPci", loopi, (FUNCPTR)intercom_device_mux_receive_return, NULL, NULL, NULL, END_INTERNODE_COMM, "END_INTERNODE_COMM", 0);
if (pRouteCookie[loopi] == NULL)
{
perror("pRouteCookie:");
printf("pChannelCookie error1\n");
}
muxMCastAddrAdd(pEnd, bAllNodeMacAddress);
muxMCastAddrAdd(pEnd, bAllSlaveMacAddress);
muxDevStart(pEnd);
/*Start ip protocol*/
ipAttach(loopi, "lnPci");
memset(ipaddr, 0, 40);
sprintf(ipaddr, "192.168.%d.%d", 237+loopi, sysProcNumGet());
usrNetIfConfig("lnPci", loopi, ipaddr, "", 0);
}
/*网口初始化结束,下面开始socket初始化和发包程序*/
/* create a socket */
sockd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockd == -1)
{
perror("Socket creation error");
exit(1);
}
/* client address */
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY;
my_addr.sin_port = 0;
bind(sockd, (struct sockaddr*)&my_addr, sizeof(my_addr));
memset(buf, 0xab, 1465);
printf("sent. buff length %d\n", strlen(buf));
/* server address */
srv_addr.sin_family = AF_INET;
inet_aton("192.168.238.2", &srv_addr.sin_addr);
srv_addr.sin_port = htons(atoi("5555"));
taskDelay(3*100);
for (loopi = 0; loopi < 2000; loopi++)
{
//printf("sent. buff length %d\n", strlen(buf));=============================1
sendto(sockd, buf, strlen(buf)+1, 0,
(struct sockaddr*)&srv_addr, sizeof(srv_addr));
//taskDelay(1);==========================2
}
printf("sent over\n");
close(sockd);
}
vxworks系统里usrAppInit函数中调用udp socket接口发包不成功,同样的代码(socket段)在Linux不用改动就可以。
环境:板上系统vxworks,板子和电脑主机直连,在主机上使用sniffer抓包
现象:
当有行1的时候(此时无行2),发包正常,从主机上可以抓到板子上发来的2000个udp报文
当有行2的时候(此时无行1),发包正常,从主机上可以抓到板子上发来的2000个udp报文
当无行1、2的时候,从主机上只能抓到板子上发来的最后一个udp报文(从ip头的identification=1999得知)
给人的感觉就是,在循环中必须得有函数调用或者是delay,循环最终才能如期待中的那样执行,如果没有就不行,而上述所有情况在Linux下面就不存在,请问这是为什么?谢谢!
[解决办法]
udp是无缓冲区的,你sendto发送的太快,全部丢给网卡了,网卡处理来不及,全部丢弃了,只处理了最后一个包!
[解决办法]
启个任务 优先级改低点
[解决办法]
你这里的sendto是阻塞调用,你的网卡BSP测试过没?是否做过性能测试
[解决办法]
参考:
问题:使用Vxworks发送数据包(20476 Byte)到Windows XP,当程序工作一段时间20分钟左右再也接收不到数据。但是如果使用 windows与windows之间,vxworks与vxworks之间数据一直接收良好。
原因: VxWorks5.5与Windows的IP分片算法不一致。 VxWorks 5.5 底层IP分片时把数据包分为了两个包(共14片:一个包为13片,共计20402个字节;一个包为1片,344字节)发送,这就导致我windows端在接收时把其当成两个包来处理,这样windows的IP层就没法把接收到的两个UDP包组合成一个UDP包上传给上层。 所以当vxworks拆分后的两个包中的任意一个丢失时,window端相当与只接收到的一个数据包一部分,就会导致数据一直错位。