消息关闭
    暂无新消息!

socket抽象命名时客户端链接失败

问题作者 : 大树2017-06-20发布

参考了很多示例,大都一样的,提示的取长度部分也注意到了.代码中两种addr_len的取法都试过,结果都是一样的.有知道原因的么?

#define SOCKET_SERVER_NAME "@/tmp/socketserver"
#define ABSTRACT_NAMESPACE_CHAR   '@'

服务端部分代码:
int main (int argc, char *argv[])
{
    int ret = 0;
    int socketFd = -1;
    int iSockOptVal = 1;
    int addr_len = 0;

    socketFd = socket (AF_UNIX, SOCK_STREAM, 0);
    if (-1 == socketFd)
    {
        printf ("socket err:%s \n", strerror (errno));
        return -1;
    }
    printf ("server socket fd=%d \n", socketFd);
    
    fcntl(socketFd, F_SETFL, fcntl(socketFd, F_GETFL) | O_NONBLOCK);
    
    struct sockaddr_un serverAddr;
    memset (&serverAddr, 0x0, sizeof (serverAddr));
    serverAddr.sun_family = AF_UNIX;
    strncpy (serverAddr.sun_path, SOCKET_SERVER_NAME, strlen (SOCKET_SERVER_NAME));
    if (ABSTRACT_NAMESPACE_CHAR == serverAddr.sun_path[0])
    {
        serverAddr.sun_path[0] = 0;
        printf ("server use abstract namespcae! \n");
        //addr_len = strlen (SOCKET_SERVER_NAME) + offsetof (struct sockaddr_un, sun_path);
        addr_len = sizeof(serverAddr.sun_family) + strlen (SOCKET_SERVER_NAME);
    }
    else
    {        
        unlink (SOCKET_SERVER_NAME);
        addr_len = sizeof(struct sockaddr_un);
    }
    
    ret = setsockopt (socketFd, SOL_SOCKET, SO_REUSEADDR, &iSockOptVal, addr_len);
    if (-1 == ret)
    {
        printf ("setsockopt err:%s \n", strerror (errno));
        close (socketFd);
        return -1;
    }

    ret = bind (socketFd, (struct sockaddr *) &serverAddr, sizeof (serverAddr));
    if (-1 == ret)
    {
        printf ("bind err:%s \n", strerror (errno));
        close (socketFd);
        return -1;
    }

    ret = listen (socketFd, SOCKET_LISTEN_NUM);
    if (-1 == ret)
    {
        printf ("listen err:%s \n", strerror (errno));
        close (socketFd);
        return -1;
    }
......
}

客户端部分代码:
int main (int argc, char *argv[])
{
    int ret = 0;
    int clientSocketFd = -1;
    char recvBuf[SOCKET_BUF_LEN] = {0};
    int addr_len = 0;
    
    clientSocketFd = socket (AF_UNIX, SOCK_STREAM, 0);
    if (-1 == clientSocketFd)
    {
        printf ("socket err:%s \n", strerror (errno));
        return -1;
    }
    printf ("clientSocketFd=%d \n", clientSocketFd);
    fcntl(clientSocketFd, F_SETFL, O_NONBLOCK);
    struct sockaddr_un serverAddr;
    memset (&serverAddr, 0x0, sizeof (serverAddr));
    serverAddr.sun_family = AF_UNIX;
    strncpy (serverAddr.sun_path, SOCKET_SERVER_NAME, strlen (SOCKET_SERVER_NAME));
    if (ABSTRACT_NAMESPACE_CHAR == serverAddr.sun_path[0])
    {
        serverAddr.sun_path[0] = 0;
        printf ("use abstract namespace! \n");
        //addr_len = strlen (SOCKET_SERVER_NAME) + offsetof (struct sockaddr_un, sun_path);
        addr_len = sizeof(serverAddr.sun_family) + strlen (SOCKET_SERVER_NAME);
    }
    else
    {
        addr_len = sizeof (struct sockaddr_un);
    }
    
//这里就报错了,errno=111,connet refused,如果是普通命名方式则没有问题(即使用"/tmp/socketserver")
    ret = connect(clientSocketFd, (struct sockaddr *)&serverAddr, addr_len);
    if (-1 == ret)
    {
        printf ("connect err:%s [%d]\n", strerror (errno), errno);
        return -1;
    }

...... 
}

5个回答

︿ 2
客户端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#define SOCKET_BUF_LEN 1024
#define SOCKET_SERVER_NAME "test.unix.socket"

int main (int argc, char *argv[])
{
    int ret = 0;
    int clientSocketFd = -1;
    char recvBuf[SOCKET_BUF_LEN] = {0};
    int addr_len = 0;
size_t size;
    
    clientSocketFd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (-1 == clientSocketFd) {
        printf("socket err:%s \n", strerror(errno));
        return -1;
    }
    printf ("clientSocketFd=%d \n", clientSocketFd);

//    fcntl(clientSocketFd, F_SETFL, O_NONBLOCK);
    struct sockaddr_un serverAddr;
    memset (&serverAddr, 0x0, sizeof (serverAddr));
    serverAddr.sun_family = AF_UNIX;
    strncpy (serverAddr.sun_path, SOCKET_SERVER_NAME, strlen (SOCKET_SERVER_NAME));
size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path);
    
    ret = connect(clientSocketFd, (struct sockaddr *)&serverAddr, size);
    if (-1 == ret) {
        printf("connect err:%s [%d]\n", strerror (errno), errno);
        return -1;
    }

write(clientSocketFd, "Hello from Client !", strlen("Hello from Client !"));
read(clientSocketFd, recvBuf, sizeof(recvBuf));

printf("[MSG] %s\n", recvBuf);
close(clientSocketFd);

return 0;



︿ 1
名字不能带@

server

#define SOCKET_SERVER_NAME "/tmp/test.unix.socket"
    memset(&serverAddr, 0x00, sizeof(serverAddr));
    serverAddr.sun_family = AF_UNIX;
serverAddr.sun_path[0] = 0;
    strncpy(serverAddr.sun_path + 1, SOCKET_SERVER_NAME, strlen(SOCKET_SERVER_NAME));
size = offsetof(struct sockaddr_un, sun_path) + sizeof(serverAddr.sun_path);
    ret = bind(socketFd, (struct sockaddr *)&serverAddr, size);



client

#define SOCKET_SERVER_NAME "/tmp/test.unix.socket"
    struct sockaddr_un serverAddr;
    memset (&serverAddr, 0x0, sizeof (serverAddr));
    serverAddr.sun_family = AF_UNIX;
serverAddr.sun_path[0] = 0;
    strncpy (serverAddr.sun_path + 1, SOCKET_SERVER_NAME, strlen(SOCKET_SERVER_NAME));
size = offsetof(struct sockaddr_un, sun_path) + sizeof(serverAddr.sun_path);


结果

root@localhost:/study/unix_socket# netstat -an | grep test
unix  2      [ ACC ]     STREAM     LISTENING     746371   @/tmp/test.unix.socket
root@localhost:/study/unix_socket# 

︿ 0
仅供参考
服务端

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/epoll.h>

#define MAX_EVENTS 10
#define SOCKET_LISTEN_NUM 5
#define SOCKET_BUF_LEN 1024
#define SOCKET_SERVER_NAME "test.unix.socket"

int main (int argc, char *argv[])
{
    int ret = 0;
    int socketFd = -1;
    int iSockOptVal = 1;
    int addr_len = sizeof(int);
size_t size;
    struct sockaddr_un serverAddr;
    char recvBuf[SOCKET_BUF_LEN] = {0};
int epoll_fd, nfds, n, conn_sock;
struct epoll_event ev, events[MAX_EVENTS];

    socketFd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (-1 == socketFd) {
        printf ("socket err:%s\n", strerror(errno));
        return -1;
    }
    printf ("server socket fd=%d\n", socketFd);
    
if (0 == access(SOCKET_SERVER_NAME, F_OK)) {
unlink(SOCKET_SERVER_NAME);
    }     

    memset(&serverAddr, 0x00, sizeof(serverAddr));
    serverAddr.sun_family = AF_UNIX;
    strncpy(serverAddr.sun_path, SOCKET_SERVER_NAME, strlen(SOCKET_SERVER_NAME));
size = offsetof(struct sockaddr_un, sun_path) + strlen(serverAddr.sun_path);
    ret = bind(socketFd, (struct sockaddr *)&serverAddr, size);
    if (-1 == ret) {
        printf ("bind err:%s \n", strerror(errno));
        close (socketFd);
        return -1;
    }

    ret = listen(socketFd, SOCKET_LISTEN_NUM);
    if (-1 == ret) {
        printf ("listen err:%s \n", strerror(errno));
        close (socketFd);
        return -1;
    }

epoll_fd = epoll_create(1);
ev.events = EPOLLIN;
ev.data.fd = socketFd;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socketFd, &ev) == -1) {
perror("epoll_ctl: socketFd");
        return -1;
}

while (1) {
nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
if (nfds == -1) {
perror("epoll_wait");
return -1;
}

for (n = 0; n < nfds; ++n) {
if (events[n].data.fd == socketFd) {
conn_sock = accept(socketFd, NULL, NULL);
if (conn_sock == -1) {
perror("accept");
return -1;
}
//setnonblocking(conn_sock);
fcntl(conn_sock, F_SETFL, fcntl(socketFd, F_GETFL) | O_NONBLOCK);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) {
perror("epoll_ctl: conn_sock");
return -1;
}
} else { //fd = conn_sock
read(events[n].data.fd, recvBuf, sizeof(recvBuf));
printf("[MSG] %s\n", recvBuf);
write(events[n].data.fd, "Hello from Server", strlen("Hello from Server"));
close(events[n].data.fd);
}
}
}

close(epoll_fd);
close(socketFd);

return 0;
}