在android上实现ssdp协议时候发现在android上,局域网内发送的ssdp alive等广播包通通收不到! 不知道是不是android kernel config的问题。在模拟器和G2手机上都收不到。
测试代码如下,在linux上是可以收到的!难道是android linux kernel udp这里也修改了!
android使用的是ndk编译,使用adb 调试环境!#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>#include <sys/socket.h>
#include<netinet/in.h>
//Constant
#define BUFSIZE 2500
#define SSDP_IP "239.255.255.250"
#define SSDP_PORT 1900
#define NUM_TRY 3
#define NUM_COPY 2
#define THREAD_LIMIT 50
#define COMMAND_LEN 300
#define UpnpCloseSocket close//Error code
#define NO_ERROR_FOUND 0
#define E_REQUEST_INVALID -3
#define E_RES_EXPIRED -4
#define E_MEM_ALLOC -5
#define E_HTTP_SYNTEX -6
#define E_SOCKET -7
#define RQST_TIMEOUT 20#define AMADECD_SOCKET_NAME "/tmp/demo_socket"static int get_broadcast_data(int socket)
{
int ssdpSock = socket;
int byteReceived = 0;
struct timeval tv;
fd_set rdSet;
char requestBuf[BUFSIZE];
struct sockaddr_in clientAddr;
socklen_t socklen = 0; while( 1 ) {
tv.tv_sec= 10;
tv.tv_usec = 0;
FD_ZERO( &rdSet );
FD_SET( ssdpSock, &rdSet );
fprintf(stderr,"----ssdp select----\n");
if( select( ssdpSock+1, &rdSet, NULL, NULL,&tv ) == -1 ) {
fprintf(stderr,"Error in select call !!!\n" );
break;
} else if( FD_ISSET( ssdpSock, &rdSet ) ) {
fprintf(stderr,"----ssdpSock::readFromSSDPSocket-----------------------\n");
byteReceived = recvfrom( socket, requestBuf,
BUFSIZE - 1, 0,
( struct sockaddr * )&clientAddr, &socklen ); if( byteReceived > 0 ) { requestBuf[byteReceived] = '\0'; fprintf( stderr,"Received Multi Packet::\n%s From host [%s] \n",
requestBuf,inet_ntoa( clientAddr.sin_addr ) );
fprintf(stderr,"---------------------------------------------------\n\n");
} else {
fprintf(stderr,"----no data recv !\n" );
}
}else{
fprintf(stderr,"Error in select timeout !!!\n" );
continue;
}
}
}
int
test_ssdp_sockets( int *out )
{
int ssdpSock;
int onOff = 1;
u_char ttl = 4;
struct ip_mreq ssdpMcastAddr;
struct sockaddr_in ssdpAddr;
int option = 1;
if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
== -1 ) {
fprintf(stderr,"Error in socket operation !!!\n" );
return -1;
} onOff = 1;
if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
( char * )&onOff, sizeof( onOff ) ) != 0 ) { fprintf(stderr,"Error in set reuse addr !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
} memset( ( void * )&ssdpAddr, 0, sizeof( struct sockaddr_in ) );
ssdpAddr.sin_family = AF_INET;
// ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
ssdpAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//ssdpAddr.sin_addr.s_addr = htonl( SSDP_IP /*INADDR_ANY*/ );
ssdpAddr.sin_port = htons( SSDP_PORT );
if( bind
( ssdpSock, ( struct sockaddr * )&ssdpAddr,
sizeof( ssdpAddr ) ) != 0 ) {
fprintf(stderr,"Error in binding !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
} memset( ( void * )&ssdpMcastAddr, 0, sizeof( struct ip_mreq ) );
ssdpMcastAddr.imr_interface.s_addr = htonl( INADDR_ANY );
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
( char * )&ssdpMcastAddr,
sizeof( struct ip_mreq ) ) != 0 ) {
fprintf(stderr,"Error in joining" " multicast group !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
}
// result is not checked becuase it will fail in WinMe and Win9x.
setsockopt( ssdpSock, IPPROTO_IP,
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
( char * )&option, sizeof( option ) ) != 0 ) {
fprintf(stderr, "Error in setting broadcast !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
}
*out = ssdpSock;
return 0;
}int main(int argc, char * argv[])
{
int socket_fd;
int i, len;
test_ssdp_sockets(&socket_fd);
fprintf(stderr,"----get ssdp socket----\n");
if (socket_fd < 0) {
return -1;
}
get_broadcast_data(socket_fd);
close(socket_fd);
return 0;
}
测试代码如下,在linux上是可以收到的!难道是android linux kernel udp这里也修改了!
android使用的是ndk编译,使用adb 调试环境!#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>#include <sys/socket.h>
#include<netinet/in.h>
//Constant
#define BUFSIZE 2500
#define SSDP_IP "239.255.255.250"
#define SSDP_PORT 1900
#define NUM_TRY 3
#define NUM_COPY 2
#define THREAD_LIMIT 50
#define COMMAND_LEN 300
#define UpnpCloseSocket close//Error code
#define NO_ERROR_FOUND 0
#define E_REQUEST_INVALID -3
#define E_RES_EXPIRED -4
#define E_MEM_ALLOC -5
#define E_HTTP_SYNTEX -6
#define E_SOCKET -7
#define RQST_TIMEOUT 20#define AMADECD_SOCKET_NAME "/tmp/demo_socket"static int get_broadcast_data(int socket)
{
int ssdpSock = socket;
int byteReceived = 0;
struct timeval tv;
fd_set rdSet;
char requestBuf[BUFSIZE];
struct sockaddr_in clientAddr;
socklen_t socklen = 0; while( 1 ) {
tv.tv_sec= 10;
tv.tv_usec = 0;
FD_ZERO( &rdSet );
FD_SET( ssdpSock, &rdSet );
fprintf(stderr,"----ssdp select----\n");
if( select( ssdpSock+1, &rdSet, NULL, NULL,&tv ) == -1 ) {
fprintf(stderr,"Error in select call !!!\n" );
break;
} else if( FD_ISSET( ssdpSock, &rdSet ) ) {
fprintf(stderr,"----ssdpSock::readFromSSDPSocket-----------------------\n");
byteReceived = recvfrom( socket, requestBuf,
BUFSIZE - 1, 0,
( struct sockaddr * )&clientAddr, &socklen ); if( byteReceived > 0 ) { requestBuf[byteReceived] = '\0'; fprintf( stderr,"Received Multi Packet::\n%s From host [%s] \n",
requestBuf,inet_ntoa( clientAddr.sin_addr ) );
fprintf(stderr,"---------------------------------------------------\n\n");
} else {
fprintf(stderr,"----no data recv !\n" );
}
}else{
fprintf(stderr,"Error in select timeout !!!\n" );
continue;
}
}
}
int
test_ssdp_sockets( int *out )
{
int ssdpSock;
int onOff = 1;
u_char ttl = 4;
struct ip_mreq ssdpMcastAddr;
struct sockaddr_in ssdpAddr;
int option = 1;
if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
== -1 ) {
fprintf(stderr,"Error in socket operation !!!\n" );
return -1;
} onOff = 1;
if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
( char * )&onOff, sizeof( onOff ) ) != 0 ) { fprintf(stderr,"Error in set reuse addr !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
} memset( ( void * )&ssdpAddr, 0, sizeof( struct sockaddr_in ) );
ssdpAddr.sin_family = AF_INET;
// ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
ssdpAddr.sin_addr.s_addr = htonl(INADDR_ANY);
//ssdpAddr.sin_addr.s_addr = htonl( SSDP_IP /*INADDR_ANY*/ );
ssdpAddr.sin_port = htons( SSDP_PORT );
if( bind
( ssdpSock, ( struct sockaddr * )&ssdpAddr,
sizeof( ssdpAddr ) ) != 0 ) {
fprintf(stderr,"Error in binding !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
} memset( ( void * )&ssdpMcastAddr, 0, sizeof( struct ip_mreq ) );
ssdpMcastAddr.imr_interface.s_addr = htonl( INADDR_ANY );
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
( char * )&ssdpMcastAddr,
sizeof( struct ip_mreq ) ) != 0 ) {
fprintf(stderr,"Error in joining" " multicast group !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
}
// result is not checked becuase it will fail in WinMe and Win9x.
setsockopt( ssdpSock, IPPROTO_IP,
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
( char * )&option, sizeof( option ) ) != 0 ) {
fprintf(stderr, "Error in setting broadcast !!!\n" );
shutdown( ssdpSock, 2 );
UpnpCloseSocket( ssdpSock );
return -1;
}
*out = ssdpSock;
return 0;
}int main(int argc, char * argv[])
{
int socket_fd;
int i, len;
test_ssdp_sockets(&socket_fd);
fprintf(stderr,"----get ssdp socket----\n");
if (socket_fd < 0) {
return -1;
}
get_broadcast_data(socket_fd);
close(socket_fd);
return 0;
}
看到了如下的文章,看来是kernel的问题了! http://code.google.com/p/android/issues/detail?id=8407
有哪位大侠也遇到过类似的处理吗?