android jni socket
2019-07-13 01:51发布
生成海报
本文由 @lonelyrains 出品,转载请注明出处。
文章链接: http://blog.csdn.net/lonelyrains/article/details/8313755
其实这个标题没什么意思;但是想来想去,自己(新手)查了很多资料才调通,就打算在此一写。
android-jni的socket编程,就是调用底层linux的socket编程。android平台,一般只需要关心客户端代码,如下:(从华清远见嵌入式linux应用开发教材上copy的,手头没好点的例子)
/*client.c*/
#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);
/*创建socket*/
if ((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)
{
perror("socket");
exit(1);
}
/*设置sockaddr_in 结构体中相关参数*/
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);
/*调用connect函数主动发起对服务器端的连接*/
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)
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;
//LOGI("recv error");
//LOGII(errno,"recv errno",__LINE__); // 11 : Resource temporarily unavailable
}
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需要添加网络权限支持才能调通:
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮