在 C 中使用 bind() 的无效参数

Invalid argument using bind() in C

这是应该创建套接字并进行绑定的代码

#include<stdio.h>
#include<stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>
#include <unistd.h>

#define SOCKNAME "./serverSC"

#define RETURNSYSCALL(r, c, e) if((r=c) == -1) {perror(e); exit(errno);}
#define SYSCALL(c, e) if(c == -1) {perror(e); exit(errno);}

void cleanup();

int main()
{
    cleanup();
    atexit(cleanup);

    int socketFd, socketComFd;
    struct sockaddr_un socketName;

    memset(&socketName, '0', sizeof(socketName));
    socketName.sun_family = AF_UNIX;
    strncpy(socketName.sun_path, SOCKNAME, strlen(SOCKNAME)+1);

    RETURNSYSCALL(socketFd, socket(AF_UNIX, SOCK_STREAM, 0), "Impossibile creare una socket");    
    SYSCALL(bind(socketFd, (struct sockaddr *) &socketName, sizeof(socketFd)), "Impossibile fare la bind");
    SYSCALL(listen(socketFd, 10), "Impossibile fare la listen");
    RETURNSYSCALL(socketComFd, accept(socketFd, NULL, 0), "impossibile fare la accept");

    return 0;
}

void cleanup() {
  unlink(SOCKNAME);
}

但是它打印的输出是:

Impossibile fare la bind: Invalid argument

有些人建议使用“AF_INET”而不是“AF_UNIX”,但这也不起作用。

bind()的第三个参数是地址的大小,所以在本例中应该是sizeof(socketName),而不是sizeof(socketFd) .

memset(&socketName, '0', sizeof(socketName));

'0' 毫无意义。使用 0(无引号)。

strncpy(socketName.sun_path, SOCKNAME, strlen(SOCKNAME)+1);

strncpy 的大小参数意味着 目标缓冲区 的大小,而不是源字符串。后者是完全无用的。如果你想复制整个源字符串,只需使用 strcpy,它就是这样做的。此外,strncpy 是一个危险的函数,应谨慎使用。它不一定以 null 终止目标缓冲区,人们往往会忘记这一点。如果你坚持,就这样做:

strncpy (socketName.sun_path, SOCKNAME, sizeof(socketName.sun_path));
socketName.sun_path[sizeof(socketName.sun_path) - 1] = 0;

最后,sizeof(socketFd) 应该是 sizeof(socketName)