Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sockets 在Android NDK中使用Socket()_Sockets_Android Ndk - Fatal编程技术网

Sockets 在Android NDK中使用Socket()

Sockets 在Android NDK中使用Socket(),sockets,android-ndk,Sockets,Android Ndk,我有一个关于在本机c程序中使用以下行的问题: #include <sys/socket.h> #include <errno.h> void testSocket() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); int err = errno; } #包括 #包括 void testSocket() { int sockfd=套接字(AF_INET,SOCK_STREAM,0); int err=er

我有一个关于在本机c程序中使用以下行的问题:

#include <sys/socket.h>
#include <errno.h>

void testSocket()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    int err = errno;
}
#包括
#包括
void testSocket()
{
int sockfd=套接字(AF_INET,SOCK_STREAM,0);
int err=errno;
}
无法创建套接字(sockfd=-1),错误号为13。我的清单中定义了以下内容:

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

有谁能告诉我他们有什么经验/知道为什么这样做行不通吗?我在这一点上拉空了。

这个答案中帮助我的部分是: 您必须添加以下行:

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

在AndroidManifest.xml中的应用程序标记之外


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

    </application>
</manifest>
AndroidManifest.xml中的应用程序标记 注意放置的位置; 如下:my AndroidManifest.xml ---------------------------------------
Application.mk
--------------
应用程序\项目\路径:=$(调用我的目录)
APP_模块:=mylib
#--------------------------------------------------------------------------------
【以下是几个C文件】
NativeHello.c,主要的C文件,调用其它普通linux本机c
-----------------------------------------------------
#包括
#包括
#包括
#包括
#包括
#包括“HttpGet.h”
JNIEXPORT jstring JNICALL native_hello(JNIEnv*env,jclass clazz)
{
printf(“c本机代码中的hello./n”);
mmain();
return(*env)->NewStringUTF(env,“--------------hello world mmain()。--------------”;
}
#定义JNIREG_类“org/eshock/jnitest/jnitest”//指定要注册的类
//注意:是类名
/***与单个类关联的方法表*/
静态JNITIVEMETHOD gMethods[]={
{“hello”,“()Ljava/lang/String;”,(void*)native_hello}//绑定
};/**为一个类注册几个本机方法*/
静态int registerActiveMethods(JNIEnv*env,const char*className,jniativeMethod*gMethods,int numMethods)
{
jclass-clazz;
clazz=(*env)->FindClass(env,className);
if(clazz==NULL)
{
返回JNI_FALSE;
}
如果((*env)->注册者(env、clazz、gMethods、numMethods)<0)
{
返回JNI_FALSE;
}
返回JNI_TRUE;}
/**为我们知道的所有类注册本机方法*/
静态int注册表项(JNIEnv*env)
{
if(!registerNativeMethods(env,JNIREG_类,gMethods,sizeof(gMethods)/sizeof(gMethods[0]))
{
返回JNI_FALSE;
}
返回JNI_TRUE;
}
/**设置一些测试内容。**成功时返回JNI版本,失败时返回-1。
*当安卓的虚拟机(虚拟机)执行到System.loadLibrary()函数时,首先会去执行C组件里的JNI_OnLoad()函数。
*它的用途有二:
*(1)【版本】告诉虚拟机此C组件使用那一个JNI版本。如果你的*.所以档没有提供JNI_OnLoad()函数,虚拟机会默认该*.所以档是使用最老的JNI 1.1版本。
*   由于新版的JNI做了许多扩充,如果需要使用JNI的新版功能,例如JNI 1.4的java.nio.ByteBuffer,
*   就必须藉由JNI_OnLoad()函数来告知虚拟机
*(2)【初始化】由于虚拟机执行到System.loadLibrary()函数时,就会立即先呼叫JNI_OnLoad()所以C组件的开发者可以藉由JNI_OnLoad()
*   来进行C组件内的初期值之设定(初始化)
* */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM*vm,void*reserved)
{
JNIEnv*env=NULL;
jint结果=-1;
if((*vm)->GetEnv(vm,(void**)和env,JNI_版本1_4)!=JNI_OK)
{
返回-1;
}
断言(env!=NULL);
如果(!注册地址(env))//注册
{
返回-1;
}
/*成功--返回有效的版本号*/
结果=JNI_版本_1_4;
返回结果;
}
--------------------------------------------
HttpGet.c
#包括“HttpGet.h”
#包括
int GetHttpResponseHead(int sock,char*buf,int size)
{
int i;
字符*代码,*状态;
memset(buf,0,大小);
对于(i=0;i=size-1){
放置(“Http响应头太长”);
返回-2;
}
代码=strstr(buf,“200”);
状态=strstr(buf,“\r\n”);
如果(!代码| |代码>状态){
*状态=0;
printf(“错误的http响应:\%s\”\n),buf);
返回-3;
}
返回i;
}
int HttpGet(常量字符*服务器,常量字符*url)
{
__android_log_print(android_log_INFO,“----from--jni------”,“enterhttpget函数!”);
int sock=socket(PF_INET,sock_STREAM,0);
__android_log_print(android_log_INFO,“----from--jni-->,“%d”,sock);
peerAddr中的结构sockaddr_;
char-buf[2048];
int ret;
//常量字符*文件名;
//FILE*fp=NULL;
peerAddr.sin_family=AF_INET;
peerAddr.sin_port=htons(80);
peerAddr.sin\u addr.s\u addr=inet\u addr(服务器);
ret=connect(sock,(struct sockaddr*)和peerAddr,sizeof(peerAddr));
如果(ret!=0){
perror(“连接失败”);
关闭(袜子);
返回-1;
}
斯普林特,
“获取%s HTTP/1.1\r\n”
“接受:*/*\r\n”
“用户代理:cnzhuhai@163.com\r\n“
“主机:%s\r\n”
“连接:关闭\r\n\r\n”,
url,服务器);
发送(sock、buf、strlen(buf)、0);
if(GetHttpResponseHead(sock、buf、sizeof(buf))0)
{
//fwrite(buf,ret,1,fp);
__android_log_print(android_log_INFO,“----from--jni-----------”,“您好,这是我的号码%s日志消息!”,buf);
}
//}
//fclose(fp);
停机(sock、SHUT\RDWR);
关闭(袜子);
返回0;
}
//"http://192.168.7.222/index.html"
国际货币基金组织(无效)
{
__android_log_print(android_log_INFO,“----from--jni------”,“Enter mmain function!”);
字符*头,*尾;
字符服务器[128]={0};
/*如果(argc1500){
放置(“Url太长”);
返回-1;
}*/
//水头=strstr(“http://192.168.10.101/gi/1.html","//");
水头=strstr(“http://220.181.111.148/index.html","//");
如果(!头){
puts(“错误的url格式”);
返回-1;
}
水头+=2;
尾部=strchr(头部“/”);
如果(!tail){
返回HttpG
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. */

static int registerNativeMethods(JNIEnv* env, const char* 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. */
static int registerNatives(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>

int GetHttpResponseHead(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;
}

int HttpGet(const char *server,const char *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);
    struct sockaddr_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);
    return 0;
}

//"http://192.168.7.222/index.html"
int mmain(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){
        return HttpGet(head,"/");
    }else if(tail-head>sizeof(server)-1){
        puts("Bad url format");
        return -1;
    }else{
        memcpy(server,head,tail-head);
        return HttpGet(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>

int GetHttpResponseHead(int sock,char *buf,int size);
int HttpGet(const char *server,const char *url);
int mmain(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)
#--------------------------------------------------------------------------------