android jni socket

本文由 @lonelyrains 出品,转载请注明出处。 
文章链接: http://blog.csdn.net/lonelyrains/article/details/8313755


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

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

/*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)

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

<!-- 增加jni socket支持-->
	<uses-permission android:name="android.permission.INTERNET" /> 


你可能感兴趣的:(android jni socket)