Skip to content Skip to sidebar Skip to footer

Using Socket() In Android Ndk

I have a question about using the following line in a native c program: #include #include void testSocket() { int sockfd = socket(AF_INET,

Solution 1:

What permission do I need to access Internet from an android application?

The part of this answer which helped me was this: You have to add this line:

<uses-permissionandroid:name="android.permission.INTERNET" />

outside the application tag in your AndroidManifest.xml

Solution 2:

Application.mk
--------------
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES      := mylib

#--------------------------------------------------------------------------------

【以下是几个c文件】
NativeHello.c ,主要的C文件,调用其它普通linux native c
-----------------------------------------------------
#include<stdlib.h>#include<string.h>#include<stdio.h>#include<jni.h>#include<assert.h>#include"HttpGet.h"

JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz)
{
    printf("hello in c native code./n");
    mmain();
    return (*env)->NewStringUTF(env, "-------------hello world mmain().-------------");
}

#define JNIREG_CLASS "org/eshock/jnitest/JNITest"//指定要注册的类//注意:是类名/** * Table of methods associated with a single class. */static JNINativeMethod gMethods[] = {
        { "hello", "()Ljava/lang/String;", (void*)native_hello },//绑定
        }; /* * Register several native methods for one class. */staticintregisterNativeMethods(JNIEnv* env, constchar* className, JNINativeMethod* gMethods, int numMethods){
    jclass clazz;
    clazz = (*env)->FindClass(env, className);
    if (clazz == NULL)
    {
        return JNI_FALSE;
    }
    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0)
    {
        return JNI_FALSE;
    }

    return JNI_TRUE; }

/* * Register native methods for all classes we know about. */staticintregisterNatives(JNIEnv* env){
    if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, sizeof(gMethods) / sizeof(gMethods[0])))
    {
        return JNI_FALSE;
    }
    return JNI_TRUE;
}

/* * Set some test stuff up. * * Returns the JNI version on success, -1 on failure.
 *当Android的VM(Virtual Machine)执行到System.loadLibrary()函数时,首先会去执行C组件里的JNI_OnLoad()函数。
 *它的用途有二:
 *(1)【版本】告诉VM此C组件使用那一个JNI版本。如果你的*.so档没有提供JNI_OnLoad()函数,VM会默认该*.so档是使用最老的JNI 1.1版本。
 *   由于新版的JNI做了许多扩充,如果需要使用JNI的新版功能,例如JNI 1.4的java.nio.ByteBuffer,
 *   就必须藉由JNI_OnLoad()函数来告知VM。
 *(2)【初始化】由于VM执行到System.loadLibrary()函数时,就会立即先呼叫JNI_OnLoad(),所以C组件的开发者可以藉由JNI_OnLoad()
 *   来进行C组件内的初期值之设定(Initialization) 。
  * */JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
    JNIEnv* env = NULL;
    jint result = -1;
    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK)
    {
        return-1;
    }
    assert(env != NULL);
    if (!registerNatives(env))//注册
    {
        return-1;
    }
    /* success -- return valid version number */
    result = JNI_VERSION_1_4;
    return result;
}

--------------------------------------------
HttpGet.c
#include"HttpGet.h"#include<android/log.h>intGetHttpResponseHead(int sock,char *buf,int size){
    int i;
    char *code,*status;
    memset(buf,0,size);
    for(i=0; i<size-1; i++){
        if(recv(sock,buf+i,1,0)!=1){
            perror("recv error");
            return-1;
        }
        if(strstr(buf,"\r\n\r\n"))
            break;
    }
    if(i >= size-1){
        puts("Http response head too long.");
        return-2;
    }
    code=strstr(buf," 200 ");
    status=strstr(buf,"\r\n");
    if(!code || code>status){
        *status=0;
        printf("Bad http response:\"%s\"\n",buf);
        return-3;
    }
    return i;
}

intHttpGet(constchar *server,constchar *url){
    __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter HttpGet function!");
    int sock=socket(PF_INET,SOCK_STREAM,0);
    __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "%d",sock);
    structsockaddr_in peerAddr;
    char buf[2048];
    int ret;
    //const char *filename;//FILE *fp=NULL;
    peerAddr.sin_family=AF_INET;
    peerAddr.sin_port=htons(80);
    peerAddr.sin_addr.s_addr=inet_addr(server);
    ret=connect(sock,(struct sockaddr *)&peerAddr,sizeof(peerAddr));
    if(ret != 0){
        perror("connect failed");
        close(sock);
        return-1;
    }
    sprintf(buf,
        "GET %s HTTP/1.1\r\n""Accept: */*\r\n""User-Agent: cnzhuhai@163.com\r\n""Host: %s\r\n""Connection: Close\r\n\r\n",
        url,server);
    send(sock,buf,strlen(buf),0);
    if(GetHttpResponseHead(sock,buf,sizeof(buf))<1){
        close(sock);
        return-1;
    }
    //filename=strrchr(url,'/')+1;//if(!filename[0])//filename="index.html";//fp=fopen(filename,"wb");//if(fp)//{
        __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter HttpGet function's while!");
        while((ret=recv(sock,buf,sizeof(buf),0)) > 0)
        {
            //fwrite(buf,ret,1,fp);
            __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "hello, this is my number %s log message!", buf);
        }
    //}//fclose(fp);shutdown(sock,SHUT_RDWR);
    close(sock);
    return0;
}

//"http://192.168.7.222/index.html"intmmain(void){
    __android_log_print(ANDROID_LOG_INFO, "-----from--jni-------", "Enter mmain function!");
    char *head,*tail;
    char server[128]={0};
/*  if(argc<2){
        printf("Usage:%s url\n",argv[0]);
        return -1;
    }
    if(strlen(argv[1])>1500){
        puts("Url too long.");
        return -1;
    }*///head=strstr("http://192.168.10.101/gi/1.html","//");
    head=strstr("http://220.181.111.148/index.html","//");
    if(!head){
        puts("Bad url format");
        return-1;
    }
    head+=2;
    tail=strchr(head,'/');
    if(!tail){
        returnHttpGet(head,"/");
    }elseif(tail-head>sizeof(server)-1){
        puts("Bad url format");
        return-1;
    }else{
        memcpy(server,head,tail-head);
        returnHttpGet(server,tail);
    }
}

HttpGet.h
---------------------------
#include<stdlib.h>#include<stdio.h>#include<string.h>#include<fcntl.h>#include<ctype.h>#include<unistd.h>#include<netdb.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/socket.h>#include<netinet/in.h>#include<arpa/inet.h>intGetHttpResponseHead(int sock,char *buf,int size);
intHttpGet(constchar *server,constchar *url);
intmmain(void);

android.mk
--------------------

include $(CLEAR_VARS)
LOCAL_LDLIBS := -lm -llog  
LOCAL_SHARED_LIBRARIES := liblog libcutils

LOCAL_MODULE    := mylib
LOCAL_SRC_FILES := \
    NativeHello.c \
    HttpGet.h \
    HttpGet.c \ 

include $(BUILD_SHARED_LIBRARY)
#--------------------------------------------------------------------------------

Solution 3:

<uses-permissionandroid:name="android.permission.INTERNET" /> 
the application tag in your AndroidManifest.xml
注意放置的位置;
如下:my AndroidManifest.xml
---------------------------------------
<?xml version="1.0" encoding="utf-8"?><manifestxmlns:android="http://schemas.android.com/apk/res/android"package="org.eshock.jnitest"android:versionCode="1"android:versionName="1.0"><uses-permissionandroid:name="android.permission.INTERNET" /><applicationandroid:icon="@drawable/icon"android:label="@string/app_name"><activityandroid:name=".JNITest"android:label="@string/app_name"><intent-filter><actionandroid:name="android.intent.action.MAIN" /><categoryandroid:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>

Post a Comment for "Using Socket() In Android Ndk"