当前位置: 首页 > 知识库问答 >
问题:

C和Go之间的抽象Unix套接字

鲁淇
2023-03-14

我正在使用一个抽象的Unix套接字在C和Go程序之间传递数据。C程序正在创建套接字,而Go程序连接到套接字。问题是Go程序无法连接到套接字,我收到以下错误消息:

UDS connection failed: dial unixgram @uds-js: connect: connection refused

下面是C程序:

#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

/* Buffer size for the receive socket */
#define BUFFER_SIZE 4096

/* The abstract Unix domain socket address name */
#define UDS_ADDRESS_NAME "#uds-js"

int main() {
    int socket_fd;
    int bytes_received;
    char buffer[BUFFER_SIZE];
    struct sockaddr_un server_address;
    struct sockaddr_un client_address;
    socklen_t address_length = sizeof(struct sockaddr_un);

    /* Create local unix socket */
    if ( ( socket_fd = socket ( AF_UNIX, SOCK_DGRAM, 0 ) ) < 0 ) {
        printf ( "socket error\n" );
        return 1;
    }

    /* Set an abstract socket address */
    memset( &server_address, 0, sizeof(server_address) );
    server_address.sun_family = AF_UNIX;
    strcpy( server_address.sun_path, UDS_ADDRESS_NAME );
    server_address.sun_path[0] = '\0';

    /* Bind socket to address */
    if ( bind ( socket_fd, (const struct sockaddr *) &server_address, address_length ) < 0 ) {
        close ( socket_fd );
        printf ( "socket bind error\n" );
        return 1;
    }
    bytes_received =
            recvfrom(
                socket_fd,
                &buffer,
                BUFFER_SIZE,
                0,
                (struct sockaddr *) &client_address,
                &address_length );
    printf ( "Received: %s\n", buffer );
    return 0;
}

和Go程序:


import (
    "fmt"
    "net"
    "os"
)

func main() {
    addr, _ := net.ResolveUnixAddr("unixgram", "@uds-js")
    udsSock, err := net.DialUnix("unixgram", nil, addr)
    if err != nil {
        fmt.Printf("UDS connection failed: %v\n", err)
        os.Exit(1)
    }
    defer udsSock.Close()
    if _, err := udsSock.Write([]byte("{\"test\":100}")); err != nil {
        fmt.Printf("Failed to send message on UDS: %v\n", err)
    }
}

在C程序中,我将套接字名称中的第一个字节设置为空字节,就像Spec一样。根据我在Go中收集的信息,名称需要以@开头。

运行netstat我可以看到套接字已创建:

$ netstat -ax | grep DGRAM
unix  2      [ ]         DGRAM                    12411992 @uds-js@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

为什么Go程序无法连接到套接字?

编辑2:

我用Go为抽象套接字创建了一个服务器,用C创建了一个客户机,两个C程序和两个Go程序可以一起工作。问题似乎是从C到使用抽象套接字。

共有1个答案

栾景胜
2023-03-14

Go程序连接到错误的抽象套接字(或者,等价地,C程序绑定到错误的抽象套接字)。

您的bind()是针对长度sizeof(struct sockaddr_un)的抽象命名空间UNIX套接字地址进行的。但是,如果我正确地读取了Go实现,您的connect()是针对长度为9的套接字地址执行的:sa_family为两个字节,本例中为len(name)为七个字节。

那是不同的插座。

在抽象命名空间中,NULL并不特殊,因此“\0uds-js是一个有效的套接字地址,“\0uds-js\0\0\0\0\0\0\0\0...”是一个不同的有效地址。

将两个进程连接在C程序的bind()和Go程序的connect()上。我希望您会看到他们用不同的socklen_t参数调用那些函数。

 类似资料:
  • 本文向大家介绍C#程序中抽象类和接口之间的区别,包括了C#程序中抽象类和接口之间的区别的使用技巧和注意事项,需要的朋友参考一下 众所周知,C#和Java一样,都是面向对象的程序设计,并且为诸如封装,抽象,继承和多态性等面向对象的概念提供全面支持。 与抽象相反,抽象类和接口都以图片形式出现,因为它们都在C#程序中提供了抽象。 在抽象类中,我们可以创建需要由派生类实现的功能。接口允许我们定义一个或多个

  • 问题内容: 我想在Unix套接字上使用node-ipc在NodeJS和C程序之间进行通信,根据该主页,这是最快的选择。(它们将在同一台计算机上)。该软件包声称它可以与C程序通信。(我必须进行健全性检查)。 问题在于示例没有提供示例C代码,而且我几乎不知道如何让他们交谈。 谁能指出我一个C代码示例以匹配那些客户机/服务器示例?例如,我将如何改编本教程以在C中使用unix管道(假设我还没有完全脱离轨道

  • SAL组件初始化接口 函数 int  sal_init (void)   SAL组件初始化   int  sal_proto_family_register (const struct proto_family *pf)   网络协议簇注册   详细描述 SAL组件初始化接口 函数说明 int sal_init ( void  ) SAL组件初始化 该函数完成对组件中使用的互斥锁等资源的初始化。

  • 本文向大家介绍Go和C ++之间的区别。,包括了Go和C ++之间的区别。的使用技巧和注意事项,需要的朋友参考一下 走 Go是一种过程编程语言。程序是使用程序包组装的。它支持类似于动态语言的环境采用模式。 C ++ C ++是一种面向对象的编程语言。C ++安静,快速,可靠且安全。它也是最广泛使用的语言。 以下是Go和C ++之间的重要区别。 序号 键 走 C ++ 1 类型 Go是一种过程编程语

  • 问题内容: 我接受了一次采访,面试官首先问我抽象类与所有抽象方法和接口之间的区别是什么。 我回答说,如果将来需要继承某些东西,并且已经扩展了一个类,那么您将无法做到这一点。 然后,他说,在这种情况下,您将永远不必扩展任何其他课程,而您必须执行合同。在这种情况下,最好使用抽象类或接口? 我告诉他您可以使用其中任何一个,但他并不满意。我不明白为什么-我认为这是开发人员/设计的选择。 问题答案: 表示接

  • 问题内容: Python中的抽象类和接口有什么区别? 问题答案: 有时您会看到以下内容: 因为Python没有(也不需要)正式的Interface协定,所以抽象和接口之间不存在Java风格的区别。如果有人努力定义一个正式的接口,它也将是一个抽象类。唯一的区别在于文档字符串中所述的意图。 当您进行鸭类输入时,抽象和接口之间的区别是令人不解的事情。 Java使用接口是因为它没有多重继承。 由于Pyth