C 中的 Connect() 函数,参数无效

Connect() function in C, invalid argument

我正在编写 client/server,客户端只需向服务器发送一条消息,他将打印该消息。

为此,我使用了套接字和本地主机。这是代码:

服务器:

    #include <unistd.h> 
    #include <stdio.h> 
    #include <sys/socket.h> 
    #include <stdlib.h> 
    #include <netinet/in.h> 
    #include <string.h>
    #include <sys/un.h> 
    #include <sys/socket.h>
    #include"thpool.h"
    #include"functions.h"
    #define N 7
    #define SERVER_PATH "/tmp/server"

    int main(void){
        unlink(SERVER_PATH);
        struct sockaddr_un stru;
        int sock_serv, new_sock;
        int opt = 1;
        struct sockaddr* cliaddr;
        char buff[N];

        cliaddr = malloc(sizeof(struct sockaddr));
        socklen_t addrlen = strlen((char* )cliaddr);

        if((sock_serv = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
            printf("socket creation error");
            exit(-1);
        }

        bzero(&stru, sizeof(struct sockaddr_in)); 

        stru.sun_family = AF_UNIX ;
        strncpy (stru.sun_path, SERVER_PATH, sizeof(stru.sun_path));

        if((bind(sock_serv, (struct sockaddr*) &stru , sizeof(struct sockaddr_un ))) < 0){
            perror("bind failed"); 
            exit(EXIT_FAILURE); 
        }

        if(listen(sock_serv, SOMAXCONN) < 0){
            perror("listen error\n");
            exit(EXIT_FAILURE); 
        }

        if((new_sock = accept(sock_serv, NULL, 0)) < 0){
            perror("accept error\n");
            exit(EXIT_FAILURE); 
        }

        read(new_sock , buff, N) ;
        printf("Server got: %s\n" , buff);

        close(sock_serv);
        close(new_sock);

        unlink(SERVER_PATH);
        return 0;
    }

这是客户:

#include <unistd.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h>
#include <sys/un.h> 
#include <sys/socket.h>
#include<errno.h>
#include"thpool.h"
#include"functions.h"
#define SERVER_PATH "/tmp/server"

int  main(void){

    int sock_cl;

    struct sockaddr* sa;
    socklen_t sa_lenght;
    sa = malloc(sizeof(struct sockaddr));
    sa_lenght = strlen((char* )sa);

    if((sock_cl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
        perror("socket creation error");
        exit(EXIT_FAILURE); 
    }

    sa->sa_family = AF_UNIX ;
    strncpy (sa->sa_data, SERVER_PATH, sizeof(sa->sa_data));

    while (connect(sock_cl , (struct sockaddr*)&sa , (socklen_t)sa_lenght) == -1) {
        perror("connection to the server failed");
        exit(EXIT_FAILURE);             
    }

    write (sock_cl, "Hello!", 7);
    printf("message sended\n");
    close(sock_cl);

    return 0;
}

我的 connect() 函数有问题,错误是 "invalid argument"。请注意,我先执行服务器,然后执行客户端,所以不是问题所在。

这就是您将 sa 定义为指向 struct sockaddr 的指针的方式。

struct sockaddr* sa;

这里你取变量sa的地址并将其转换为sa的类型

(struct sockaddr*)&sa

结果是一个指向 struct sockaddr 的指针,它被强制转换为指向 struct sockaddr 的指针。

Type-casting是个陷阱,你中了。

为了解决,我推荐使用套接字教程。
我认为在比较您的客户端和本教程中的示例客户端时,尤其是您创建的指针级别问题变得非常明显:
https://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html

您的服务器和客户端都在滥用 sockaddr... 结构。服务器端的错误不会影响任何东西,因为它实际上并没有使用它分配的错误 sockaddr,它只是泄漏。但是您的客户完全滥用了传递给 connect()sockaddr,这就是 connect() 失败的原因。

试试这个:

服务器

#include <unistd.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h>
#include <sys/un.h> 
#include <sys/socket.h>
#include "thpool.h"
#include "functions.h"

#define N 7
#define SERVER_PATH "/tmp/server"

int main(void){
    unlink(SERVER_PATH);

    struct sockaddr_un stru;
    int sock_serv, new_sock;
    ssize_t bufflen;
    char buff[N];

    if((sock_serv = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
        printf("socket creation error");
        exit(-1);
    }

    bzero(&stru, sizeof(stru));
    stru.sun_family = AF_UNIX;
    strncpy (stru.sun_path, SERVER_PATH, sizeof(stru.sun_path));

    if((bind(sock_serv, (struct sockaddr*) &stru, sizeof(stru))) < 0){
        perror("bind error");
        exit(EXIT_FAILURE); 
    }

    if(listen(sock_serv, SOMAXCONN) < 0){
        perror("listen error");
        exit(EXIT_FAILURE); 
    }

    if((new_sock = accept(sock_serv, NULL, 0)) < 0){
        perror("accept error");
        exit(EXIT_FAILURE); 
    }

    bufflen = read(new_sock, buff, N);
    if (bufflen < 0) {
        perror("read error");
    }
    else if (bufflen == 0) {
        printf("Client disconnected\n");
    }
    else {
        printf("Server got: %.*s\n", (int) bufflen, buff);
    }

    close(new_sock);
    close(sock_serv);

    unlink(SERVER_PATH);
    return 0;
}

客户

#include <unistd.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <stdlib.h> 
#include <netinet/in.h> 
#include <string.h>
#include <sys/un.h> 
#include <sys/socket.h>
#include <errno.h>
#include "thpool.h"
#include "functions.h"

#define SERVER_PATH "/tmp/server"
const char *msg = "Hello!";

int main(void){

    int sock_cl;
    struct sockaddr_un sa;
    ssize_t sent;

    if((sock_cl = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
        perror("socket creation error");
        exit(EXIT_FAILURE); 
    }

    bzero(&s, sizeof(sa));
    sa.sa_family = AF_UNIX;
    strncpy (sa.sa_data, SERVER_PATH, sizeof(sa.sa_data));

    if (connect(sock_cl, (struct sockaddr*) &sa, (socklen_t) sizeof(sa)) < 0) {
        perror("connect error");
        exit(EXIT_FAILURE);             
    }

    sent = write(sock_cl, msg, strlen(msg)+1);
    if (sent < 0) {
        perror("write error");
    }
    else {
        printf("Message sent: %.*s\n", (int) sent, msg);
    }

    close(sock_cl);
    return 0;
}