其实这个标题没什么意思;但是想来想去,自己(新手)查了很多资料才调通,就打算在此一写。
android-jni的socket编程,就是调用底层linux的socket编程。android平台,一般只需要关心客户端代码,如下:(从华清远见嵌入式linux应用开发教材上copy的,手头没好点的例子)
[cpp] view
plain copy
print?
-
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#define SERVPORT 8591
-
#define MAXDATASIZE 100
-
main(int argc,char *argv[])
-
{
-
int sockfd,sendbytes;
-
char buf[MAXDATASIZE];
-
struct hostent *host;
-
struct sockaddr_in serv_addr;
-
if (argc < 2)
-
{
-
fprintf(stderr,"Please enter the server's hostname!
");
-
exit(1);
-
}
-
-
if ((host=gethostbyname(argv[1]))==NULL)
-
{
-
perror("gethostbyname");
-
exit(1);
-
}
-
printf("%s",host->h_name);
-
-
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)
-
{
-
perror("socket");
-
exit(1);
-
}
-
-
serv_addr.sin_family=AF_INET;
-
serv_addr.sin_port=htons(SERVPORT);
-
serv_addr.sin_addr=*((struct in_addr *)host->h_addr);
-
bzero(&(serv_addr.sin_zero),8);
-
-
if (connect(sockfd,(struct sockaddr *)&serv_addr,
-
sizeof(struct sockaddr))== -1)
-
{
-
perror("connect");
-
exit(1);
-
}
-
-
if ((sendbytes=send(sockfd,"hello",5,0))== -1)
-
{
-
perror("send");
-
exit(1);
-
}
-
close(sockfd);
-
}
然后可以参照android-ndk的sample把它改成jni方式调用。
接收消息,可以采用如下方式:(参考APUE)
[cpp] view
plain copy
print?
-
long ReceiveMessage(BYTE *buf,UINT bufSize,UINT *recvbufLen,UINT nTimeOut)
-
{
-
LOGI("ReceiveMessage");
-
-
long lRet = -1;
-
-
int recvbytes;
-
uint startTime = GetTickCount(),endTime;
-
do
-
{
-
endTime = GetTickCount();
-
if ((recvbytes=recv(sockfd, buf, bufSize, MSG_DONTWAIT)) == -1)
-
{
-
lRet = -1;
-
-
-
}
-
else
-
{
-
lRet = 0;
-
break;
-
}
-
}while(lRet == -1 && endTime - startTime < nTimeOut);
-
-
*recvbufLen = recvbytes;
-
if(recvbytes > 0)
-
LOGArr((unsigned char*)buf,recvbytes);
-
-
return lRet;
-
}
上例中用指针传输出参数而不是引用,是因为是在.c文件中编译jni,不支持c++特性。而jni-c++这一部分还没完全搞清楚,等搞清楚了再写一篇。
需要说明的最重要的一点是,工程目录下的AndroidManifest.xml需要添加网络权限支持才能调通:
[html] view
plain copy
print?
-
-
<uses-permission android:name="android.permission.INTERNET" />