自动命名AF_UNIX本地数据报套接字?

时间:2020-03-06 14:22:26  来源:igfitidea点击:

我正在通过unix本地套接字(AF_UNIX地址族,即不是UDP)上的数据报实现简单的服务。服务器绑定到一个公共地址,并且可以很好地接收请求。不幸的是,在回答问题时,除非客户端也受到约束,否则" sendto"将失败。 (常见错误是"运输端点未连接")。

绑定到某个随机名称(基于文件系统或者抽象)的工作方式。但我想避免这种情况:我该保证谁选的名字不会冲突?

Unix套接字的流模式文档告诉我们,如果还没有抽象名称,则将在"连接"时为其分配一个抽象名称。这样的功能是否可用于面向数据报的套接字?

解决方案

我不确定我是否完全理解问题,但这是我刚刚编写的回显服务器的数据报实现。我们可以看到服务器在从其发送的相同IP / PORT上响应客户端。

这是代码

一,服务器(监听器)

from socket import *
import time
class Listener:
    def __init__(self, port):
        self.port = port
        self.buffer = 102400

    def listen(self):

        sock = socket(AF_INET, SOCK_DGRAM)
        sock.bind(('', self.port))

        while 1:
            data, addr = sock.recvfrom(self.buffer)
            print "Received: " + data
            print "sending to %s" % addr[0]
            print "sending data %s" % data
            time.sleep(0.25)
            #print addr # will tell you what IP address the request came from and port
            sock.sendto(data, (addr[0], addr[1]))
            print "sent"
        sock.close()

if __name__ == "__main__":
    l = Listener(1975)
    l.listen()

现在,客户端(发送方)从侦听器接收响应

from socket import *
from time import sleep
class Sender:
    def __init__(self, server):
       self.port = 1975
       self.server = server
       self.buffer = 102400

    def sendPacket(self, packet):
        sock = socket(AF_INET, SOCK_DGRAM)
        sock.settimeout(10.75)

        sock.sendto(packet, (self.server, int(self.port)))

        while 1:
            print "waiting for response"
            data, addr = sock.recvfrom(self.buffer)
            sock.close()
            return data

if __name__ == "__main__":
        s = Sender("127.0.0.1")
        response = s.sendPacket("Hello, world!")
        print response

我假设我们正在运行Linux;我不知道此建议是否适用于SunOS或者任何UNIX。

首先,答案:在socket()之后,connect()或者first sendto()之前,尝试添加以下代码:

struct sockaddr_un me;
me.sun_family = AF_UNIX;
int result = bind(fd, (void*)&me, sizeof(short));

现在,进行解释:unix(7)手册页指出:

When  a  socket  is  connected and it
  doesn’t already have a local address a
  unique address in the abstract
  namespace will be generated
  automatically.

可悲的是,手册页位于。

检查Linux源代码,我们看到,如果在套接字标志中设置了SOCK_PASSCRED,则unix_dgram_connect()仅调用unix_autobind()。由于我不知道SOCK_PASSCRED是什么,现在是凌晨1:00,因此我需要寻找另一种解决方案。

检查unix_bind时,我注意到如果传入的大小等于" sizeof(short)",则unix_bind会调用unix_autobind。因此,上面的解决方案。

祝你好运,早上好。

回应迟了一点,但是对于像我一样使用google的人来说。 Rob Adam的答案帮助我得到了"真正的"答案:只需使用set(级别SO_SOCKET,请参见man 7 unix)将SO_PASSCRED设置为1. 就不需要傻傻的绑定。

我在PHP中使用了它,但是没有定义SO_PASSCRED(愚蠢的PHP)。但是,如果我们自己定义它,它仍然可以工作。在我的计算机上,它的值为16,我认为它将非常方便地工作。