与Android NDK中的Unix域进行LocalSocket通信

问题描述 投票:9回答:3

我有Android应用程序,需要与以下应用程序建立Unix域套接字连接我们的C ++库(使用Android NDK)

public static String SOCKET_ADDRESS = "your.local.socket.address"; // STRING

java中有LocalSocket接受“字符串”(your.local.socket.address)

#define ADDRESS     "/tmp/unix.str" /* ABSOLUTE PATH */
  struct sockaddr_un saun, fsaun;
    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
        perror("server: socket");
        exit(1);
    }
    saun.sun_family = AF_UNIX;
    strcpy(saun.sun_path, ADDRESS);

但是位于本机层的unix域套接字接受“绝对路径”。那么这两方如何相互交流?

如果可能,请分享任何示例

android sockets network-programming android-ndk unix-socket
3个回答
13
投票

LocalSocket使用Linux抽象名称空间而不是文件系统。在C语言中,这些地址是通过在路径前面加上'\ 0'来指定的。

const char name[] = "\0your.local.socket.address";
struct sockaddr_un addr;
addr.sun_family = AF_UNIX;

// size-1 because abstract socket names are *not* null terminated
memcpy(addr.sun_path, name, sizeof(name) - 1);

还要注意,您不应该将sizeof(sockaddr_un)传递给bindsendto,因为'\ 0'字符后的所有字节均被解释为抽象套接字名称。计算并传递实际大小:

int res = sendto(sock, &data, sizeof(data), 0,
                 (struct sockaddr const *) &addr,
                 sizeof(addr.sun_family) + sizeof(name) - 1);

0
投票

Pro Android C++ with the NDK book, chapter 10帮助我开始了相同的工作。


0
投票

我有两个android(客户端和服务器),它们通过本机级别(C ++ / JNI)上的Unix域套接字连接。两者均使用目标API级别27构建,并且可以正常工作数年。最近,我将它们升级到API级别28,现在客户端无法连接到服务器,connect()函数返回-1,结果表明对于Android 9(API级别28),我无法连接到本地nodejs来自Android设备模拟器的服务器。如果我仅更改所有构建依赖项以使用较低的API级别(<= 27),它将正确连接。根据我对Android 9行为更改的了解,我真的不知道是什么会导致这种情况。这是我从logcat获得的日志。

com.apk.manage I/TSOCKET:  TSocket::open()
com.apk.manage I/TSOCKET:  TSocket::unix_open()
com.apk.manage I/TSOCKET:  TSocket::openConnection()
com.apk.manage I/TSOCKET:  TSocket::setLinger()
com.apk.manage I/TSOCKET:  TSocket::setNoDelay()
com.apk.manage I/TSOCKET:  TSocket::structlen = static_cast<socklen_t>(sizeof(address)) 110
com.apk.manage I/TSOCKET:  TSocket::openConnection() connect() return -1

我知道API 28请求运行时权限,并且服务和应用程序都请求并获得写入,读取和Internet运行时权限。

我的客户清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.company.client"
    android:versionCode="2"
    android:versionName="5.1.0">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_label"
        tools:replace="android:label"
        android:requestLegacyExternalStorage="true"
        android:usesCleartextTraffic="true"
        android:networkSecurityConfig="@xml/network_security_config"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.company.client.clientActivity"
            android:label="@string/app_label"
            android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.google.zxing.client.android.CaptureActivity"
            android:configChanges="orientation|keyboardHidden"
            android:screenOrientation="landscape"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:windowSoftInputMode="stateAlwaysHidden" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.google.zxing.client.android.SCAN" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity android:name="ar.com.daidalos.afiledialog.FileChooserActivity" />
    </application>

</manifest>

我的服务器清单

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.company.server"
    android:versionCode="2"
    android:versionName="5.1.0">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <uses-permission android:name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.PERSISTENT_ACTIVITY" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.FILTER_EVENTS" />

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

    <permission android:name="android.hardware.usb.host" />
    <uses-feature
        android:name="android.hardware.usb.host"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_label"
        android:requestLegacyExternalStorage="true"
        android:theme="@style/AppTheme">

        <receiver android:name="com.company.server.autostart">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <activity
            android:name="com.company.server.MainActivity"
            android:label="@string/app_label"
            android:launchMode="singleInstance"
            android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".Service"
            android:enabled="true"
            android:exported="true"
            android:isolatedProcess="false">

            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
                <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
            </intent-filter>

            <meta-data
                android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
                android:resource="@xml/devices_filter" />
            <meta-data
                android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
                android:resource="@xml/devices_filter" />
        </service>

    </application> </manifest>

如何使本地套接字连接正常工作?

© www.soinside.com 2019 - 2024. All rights reserved.