CC3200 SL_IPPROTO_RAW无法recv到IP RAW Packet,提示-11 (try again)
您好,TI工程师
我在CC3200 example code: getting_started_with_wlan_station
中有添加如下function 去sniffer IP layer的 RAW Pakcet, 但始终返回错误信息:[(PNum=×) recievedBytes= -11] :
查看-11 表示 try again , 可以麻烦看下是哪里的不对吗?
我添加的function 是按照TI wiki 中描述里进行的
http://processors.wiki.ti.com/index.php/CC31xx_%26_CC32xx_Advanced_Networking
int RawSocketRx(int iNumberOfPackets)
{
SlSockAddrIn_t Addr;
unsigned char *pbuf = NULL;
int recievedBytes = 0;
int AddrSize = 0;
int lRetVal = -1;
int iSoc = -1;
const int flag = 1;
struct SlTimeval_t timeval;
timeval.tv_sec = 0; // Seconds
timeval.tv_usec = 20000; // Microseconds. 10000 microseconds resoultion
pbuf = (unsigned char*)malloc(BUFFER_SIZE);
/* create a raw-socket following the instructions given above*/
iSoc = sl_Socket(SL_AF_INET, SL_SOCK_RAW, SL_IPPROTO_RAW);
lRetVal = sl_SetSockOpt(iSoc,SL_IPPROTO_IP,SL_IP_HDRINCL, &flag, sizeof(flag));
ASSERT_ON_ERROR(__LINE__, lRetVal);
lRetVal = sl_SetSockOpt(iSoc,SL_SOL_SOCKET,SL_SO_RCVTIMEO, &timeval, sizeof(timeval));
ASSERT_ON_ERROR(__LINE__, lRetVal);
Addr.sin_family = SL_AF_INET;
Addr.sin_port = sl_Htons((unsigned short)0);
Addr.sin_addr.s_addr = sl_Htonl(INADDR_ANY);
AddrSize = sizeof(SlSockAddrIn_t);
sl_Connect(iSoc, ( SlSockAddr_t *)&Addr, AddrSize);
while(iNumberOfPackets--)
{
memset(pbuf, 0, BUFFER_SIZE);
recievedBytes = sl_Recv (iSoc, pbuf, BUFFER_SIZE, 0);
UART_PRINT("[(PNum=%d) recievedBytes= %d] : \n\r", iNumberOfPackets,recievedBytes);
DUMP(pbuf,recievedBytes);
}
sl_Close(iSoc);
free(pbuf);
return SUCCESS;
}
今天 做了两个实验:
1: 用SOCK_STREAM 的方式 可以recv 到从TCP server端 发送过来的数据,
/* create a raw-socket following the instructions given above*/
iSoc = sl_Socket(SL_AF_INET, SL_SOCK_STREAM, 0);
Addr.sin_family = SL_AF_INET;
Addr.sin_port = sl_Htons(1234);
Addr.sin_addr.s_addr = sl_Htonl(0x0a0a0a64);
AddrSize = sizeof(SlSockAddrIn_t);
lRetVal = sl_Connect(iSoc, ( SlSockAddr_t *)&Addr, AddrSize);
if( lRetVal < 0 )
{
UART_PRINT("sl_Connect() Failed!\r\n");
ASSERT_ON_ERROR(__LINE__, lRetVal);
}
2: 替换上面黄色区域的代码为如下内容
/* create a raw-socket following the instructions given above*/
iSoc = sl_Socket(SL_AF_INET, SL_SOCK_RAW, SL_IPPROTO_RAW);
lRetVal = sl_SetSockOpt(iSoc,SL_IPPROTO_IP,SL_IP_HDRINCL, &flag, sizeof(flag));
ASSERT_ON_ERROR(__LINE__, lRetVal);
其他代码同test1 的一样,但第2次的改动,无法收到数据。
所以判断代码中其他地方应该是OK的,差异只是在SL_SOK_RAW, SL_IPPROTO_RAW 这些type/protocol的选择上,
是否TI 工程师对此可以给出一些帮助呢,非常感谢!
自己先顶一下哈,
请问是否有TI 工程师 可以帮忙看看呢? Thanks!
能否用这种方式试试看?
struct timeval timeVal;
g_RawPacketSD = sl_Socket( SL_AF_PACKET, SL_SOCK_RAW, 0 );
if( g_RawPacketSD < 0 )
{
SEND_LOG_INFO("failed open RAW Packet socket \r\n");
}
timeVal.tv_sec = 0; /* Seconds */
timeVal.tv_usec = 5000 ; /* Microseconds */
sl_SetSockOpt( g_RawPacketSD, SL_SOL_SOCKET, SL_SO_RCVTIMEO, &timeVal, sizeof(timeVal) );
Hi, YongHua
Thanks a lot! 您帮了大忙, 这种方式试验是OK的。 谢谢!
你好,
我照這個方式實作,會收到所有封包,導致連網頁也進不去,請問是否有方法可以只讀取特定封包,
以下是程式片段
iSock = sl_Socket(SL_AF_PACKET, SL_SOCK_RAW, 0);
...
while (1) {
SL_FD_ZERO(&ReadFds);
SL_FD_SET(iSock, ReadFds);
g_timeout.tv_sec = 1;
g_timeout.tv_usec = 0;
lRetVal = sl_Select(iSock + 1, &ReadFds, NULL, NULL, &g_timeout);
if (0 < lRetVal && SL_FD_ISSET(iSock, &ReadFds)) {
sl_Recv(iSock, cDataBuf, 14, 0);
SL_FD_CLR(iSock, &ReadFds);
}
}
謝謝
Ken
In linux man page http://linux.die.net/man/7/raw
An IPPROTO_RAW socket is send only.
CC3200的RAW也是可以接收的,不过不要用select去操作。