• android jni socket


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

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

    1. /*client.c*/  
    2. #include <stdio.h>  
    3. #include <stdlib.h>  
    4. #include <errno.h>  
    5. #include <string.h>  
    6. #include <netdb.h>  
    7. #include <sys/types.h>  
    8. #include <netinet/in.h>  
    9. #include <sys/socket.h>  
    10. #define SERVPORT 8591  
    11. #define MAXDATASIZE 100  
    12. main(int argc,char *argv[])  
    13. {  
    14.     int sockfd,sendbytes;  
    15.     char buf[MAXDATASIZE];  
    16.     struct hostent *host;  
    17.     struct sockaddr_in serv_addr;  
    18.     if (argc < 2)  
    19.     {  
    20.         fprintf(stderr,"Please enter the server's hostname! ");  
    21.         exit(1);  
    22.     }  
    23.     /*地址解析函数*/  
    24.     if ((host=gethostbyname(argv[1]))==NULL)  
    25.     {  
    26.         perror("gethostbyname");  
    27.         exit(1);  
    28.     }  
    29.     printf("%s",host->h_name);  
    30.     /*创建socket*/  
    31.     if ((sockfd=socket(AF_INET,SOCK_STREAM,0))== -1)  
    32.     {  
    33.         perror("socket");  
    34.         exit(1);  
    35.     }  
    36.     /*设置sockaddr_in 结构体中相关参数*/  
    37.     serv_addr.sin_family=AF_INET;  
    38.     serv_addr.sin_port=htons(SERVPORT);  
    39.     serv_addr.sin_addr=*((struct in_addr *)host->h_addr);  
    40.     bzero(&(serv_addr.sin_zero),8);  
    41.     /*调用connect函数主动发起对服务器端的连接*/  
    42.     if (connect(sockfd,(struct sockaddr *)&serv_addr,  
    43.                 sizeof(struct sockaddr))== -1)  
    44.     {  
    45.         perror("connect");  
    46.         exit(1);  
    47.     }  
    48.     /*发送消息给服务器端*/  
    49.     if ((sendbytes=send(sockfd,"hello",5,0))== -1)  
    50.     {  
    51.         perror("send");  
    52.         exit(1);  
    53.     }  
    54.     close(sockfd);  
    55. }  

    然后可以参照android-ndk的sample把它改成jni方式调用。


            接收消息,可以采用如下方式:(参考APUE)

    1. long  ReceiveMessage(BYTE *buf,UINT bufSize,UINT *recvbufLen,UINT nTimeOut)  
    2. {  
    3.     LOGI("ReceiveMessage");  
    4.   
    5.     long lRet = -1;  
    6.   
    7.     int recvbytes;  
    8.     uint startTime = GetTickCount(),endTime;  
    9.     do  
    10.     {  
    11.         endTime = GetTickCount();  
    12.         if ((recvbytes=recv(sockfd, buf, bufSize, MSG_DONTWAIT)) == -1)  
    13.         {  
    14.             lRet = -1;  
    15.             //LOGI("recv error");  
    16.             //LOGII(errno,"recv errno",__LINE__); // 11 : Resource temporarily unavailable  
    17.         }  
    18.         else  
    19.         {  
    20.             lRet = 0;  
    21.             break;  
    22.         }  
    23.     }while(lRet == -1 && endTime - startTime < nTimeOut);  
    24.   
    25.     *recvbufLen = recvbytes;  
    26.     if(recvbytes > 0)  
    27.         LOGArr((unsigned char*)buf,recvbytes);  
    28.   
    29.     return lRet;  
    30. }  


            上例中用指针传输出参数而不是引用,是因为是在.c文件中编译jni,不支持c++特性。而jni-c++这一部分还没完全搞清楚,等搞清楚了再写一篇。

         

            需要说明的最重要的一点是,工程目录下的AndroidManifest.xml需要添加网络权限支持才能调通:

    1. <!-- 增加jni socket支持-->  
    2.     <uses-permission android:name="android.permission.INTERNET" />   
  • 相关阅读:
    Java线程:线程的调度-优先级
    Java线程:线程的调度-休眠
    Java线程:线程的交互
    Java线程:线程的同步与锁
    使用GIT时排除NuGet的packages文件夹
    解决Visual Studio 2013 XAML设计器异常
    代码协定(四)——安装和使用
    在WPF 4.5中跨线程更新集合
    微软自家的.Net下的JavaScript引擎——ClearScript
    在MEF中手动导入依赖的模块
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318675.html
Copyright © 2020-2023  润新知