【发布时间】:2020-10-13 13:05:15
【问题描述】:
我正在使用抽象的 Unix 套接字在 C 和 Go 程序之间传递数据。 C 程序正在创建套接字,Go 程序连接到它。问题是 Go 程序无法连接到套接字,我收到以下错误消息:
UDS connection failed: dial unixgram @uds-js: connect: connection refused
这是 C 程序:
#include#include #include #include /* 接收套接字的缓冲区大小 */ #define BUFFER_SIZE 4096 /* 抽象的 Unix 域套接字地址名称 */ #define UDS_ADDRESS_NAME "#uds-js" int main() { int socket_fd; int bytes_received; 字符缓冲区[BUFFER_SIZE]; 结构 sockaddr_un 服务器地址; 结构 sockaddr_un 客户端地址; socklen_t address_length = sizeof(struct sockaddr_un); /* 创建本地 unix 套接字 */ if ( ( socket_fd = socket (AF_UNIX, SOCK_DGRAM, 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 程序中,我将套接字名称中的第一个字节设置为空字节,as to spec。从我收集到的in Go 中,名称需要以
@开头。运行
netstat我可以看到套接字已创建:$ netstat -ax | grep DGRAM unix 2 [ ] DGRAM 12411992 @uds-js@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@为什么Go程序连接不上socket?
编辑:
将名称更改为路径名
/tmp/uds-js,这确实按预期工作。EDIT2:
我在 Go 中为抽象套接字创建了一个服务器,在 C 中创建了一个客户端,两个 C 程序和两个 Go 程序可以正常工作。问题似乎出在使用抽象套接字从 C 转到 Go 时。
【问题讨论】:
-
如果你使套接字不是抽象的(也就是说,它在文件系统上有一个真实的路径),它是否工作?这会将问题分解为两个较小的部分。
-
也是在启动时删除套接字路径的好习惯:remove(UDS_ADDRESS_NAME),因为如果它已经存在,您将无法使用它。也不知道路径开头的#,这行得通吗?
-
@secretsquirrel,一旦所有对抽象套接字的引用丢失,抽象套接字就会消失;与“经典”UD 套接字相比,这是它们的优势。
-
哦,是的,你说得对,我以前从未使用过它们
-
你把
server_address.sun_path[0] = '\0';改成/tmp/uds-js时删除了,对吧?