In android, there are two classes LocalServerSocket and LocalSocket. I think they are something like AF_LOCAL in unix socket (I am not sure it is correct or not).
My que
Looking at local_socket_client.c
in the Android source, it looks like they do this:
int socket_make_sockaddr_un(const char *name, int namespaceId,
struct sockaddr_un *p_addr, socklen_t *alen)
{
memset (p_addr, 0, sizeof (*p_addr));
size_t namelen;
switch (namespaceId) {
case ANDROID_SOCKET_NAMESPACE_ABSTRACT:
namelen = strlen(name);
// Test with length +1 for the *initial* '\0'.
if ((namelen + 1) > sizeof(p_addr->sun_path)) {
goto error;
}
/*
* Note: The path in this case is *not* supposed to be
* '\0'-terminated. ("man 7 unix" for the gory details.)
*/
p_addr->sun_path[0] = 0;
memcpy(p_addr->sun_path + 1, name, namelen);
...
p_addr->sun_family = AF_LOCAL;
*alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1;
It seems like the memset() is important because the entire sun_path
is relevant. (looks like you cover that part with your structure initialization, though.) And it's not "0" plus the original name, it's an actual zero byte! (its value is all binary zeroes, not an ascii '0'
)
Try following more closely what they're doing, including the leading '\0' byte and the AF_LOCAL family.
If you have updated code (whether it works or not) please post it! I'm interested in your results. Did you ever get this to work?
If it doesn't work, find out what errno
is and either call perror()
to print it to stderr
, or call strerror()
and log the output. Let us know what error you get.
Edit
I recently solved this problem in a project of my own. I found that the key was to specify the correct length when calling connect()
and bind()
. In the code I posted above, it calculates the length by using the offset of the sun_path
in the structure, plus the length of the name, plus one for the leading '\0'
byte. If you specify any other length, Java code might not be able to connect to the socket.