我有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域套接字接受“绝对路径”。那么这两方如何相互交流?
如果可能,请分享任何示例
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)
传递给bind
或sendto
,因为'\ 0'字符后的所有字节均被解释为抽象套接字名称。计算并传递实际大小:
int res = sendto(sock, &data, sizeof(data), 0,
(struct sockaddr const *) &addr,
sizeof(addr.sun_family) + sizeof(name) - 1);
Pro Android C++ with the NDK book, chapter 10帮助我开始了相同的工作。
我有两个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>
如何使本地套接字连接正常工作?