嗨,我正在尝试制作一个简单的分叉程序,然后像客户端/服务器一样工作。这是我的代码:

int main (){
int sfd,fdc;
struct sockaddr_un sa;
strncpy(sa.sun_path,SOCKNAME,UNIX_PATH_MAX);
sa.sun_family = AF_UNIX;
char buf[N+1];

if (fork() != 0){
    sfd = socket(AF_UNIX,SOCK_STREAM,0);
    bind (sfd, (struct sockaddr *) &sa ,sizeof(sa));
    listen(sfd, SOMAXCONN);
    fdc= accept(sfd,NULL,0);
    read(fdc,buf,N);
    printf("Server got: %s\n",buf);
    write(fdc,"bye!",5);
    close(fdc);
    close(sfd);
    exit(EXIT_SUCCESS);
}
else {
    sfd = socket(AF_UNIX,SOCK_STREAM,0);

    while(connect(sfd, (struct sockaddr *)&sa,sizeof(sa)) == -1){
        if (errno == ENOENT){
            printf("Aspetto 1 sec\n");
            sleep(1);
        }
        else {perror(NULL); exit(EXIT_FAILURE) ;}
    }
    write(sfd,"Hallo!",7);
    read(sfd,buf,N);
    printf("Client got: %s\n",buf);
    close(sfd);
    exit(EXIT_SUCCESS);
    }


我不明白为什么在尝试将客户端连接到服务器时此操作失败。我收到此错误:连接被拒绝。
感谢您的帮助,我真的找不到问题所在。

最佳答案

首先,关于分叉然后应该像客户端/服务器一样工作的简单程序:将客户端和服务器置于同一逻辑块中不是一个好主意。尽管可以将其写成在语法上是正确的(即可以编译和构建),但我不知道它怎么会实用。

有许多教程示例,使用Posix C创建单独的服务器和客户端应用程序。 Here is oneHere is anothera third

一个普遍的建议是,在使用具有前提条件的一系列函数(例如套接字的句柄或先前成功调用另一个函数)时,应始终使用返回值。例如,在示例代码的以下行中:

if (fork() != 0){
    sfd = socket(AF_UNIX,SOCK_STREAM,0);
    bind (sfd, (struct sockaddr *) &sa ,sizeof(sa));
    listen(sfd, SOMAXCONN);
    fdc= accept(sfd,NULL,0);


您选择验证的唯一一行是fork的结果(很好)。但是,您还应该检查其他每个结果,并将结果作为继续进行下一步的先决条件。

至少是这样的:

if (fork() != 0)
{
    sfd = socket(AF_UNIX,SOCK_STREAM,0);
    if(sfd < 0)
    {
        //notify user
        return -1;
    }
    ret = bind (sfd, (struct sockaddr *) &sa ,sizeof(sa));
    if(ret < 0)
    {
        //check value of errno, and notify user
        return -1;
    }
    ret = listen(sfd, SOMAXCONN);
    if(ret < 0)
    {
        //check value of errno, and notify user
        return -1;
    }
    new_s= accept(sfd,NULL,0);
    if(new_s < 0)
    {
        //check value of errno, and notify user
        return -1;
    }
    // continue...

10-07 19:17
查看更多