您的位置:首页 > 移动开发 > Android开发

android jni socket

2016-03-19 00:01 351 查看


android jni socket

        其实这个标题没什么意思;但是想来想去,自己(新手)查了很多资料才调通,就打算在此一写。

        android-jni的socket编程,就是调用底层linux的socket编程。android平台,一般只需要关心客户端代码,如下:(从华清远见嵌入式linux应用开发教材上copy的,手头没好点的例子)

[cpp] view
plain copy

 print?

/*client.c*/  

#include <stdio.h>  

#include <stdlib.h>  

#include <errno.h>  

#include <string.h>  

#include <netdb.h>  

#include <sys/types.h>  

#include <netinet/in.h>  

#include <sys/socket.h>  

#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!\n");  

        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)

[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;  

            //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需要添加网络权限支持才能调通:

[html] view
plain copy

 print?

<!-- 增加jni socket支持-->  

    <uses-permission android:name="android.permission.INTERNET" />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: