자동화 이름의 AF_UNIX 로컬 데이터그램 소켓?
문제
나를 구현하는 간단하는 서비스를 사용하여 데이터그램을 통해 유닉스 로컬 소켓(AF_UNIX 주소를 가족,즉 지 UDP).서버를 바인딩하여 공공 장소,그리고 요청을 받을됩니다.불행하게도,그것은 응답을 다시, sendto
실패하지 않으면 클라이언트밖에 없 too.(일반적인 오류가입 Transport endpoint is not connected
).
에 바인딩하는 몇 가지의 이름(파일 시스템을 기반 또는 추상)작동합니다.그러나고 싶지:내가 누구를 보장하는 이름을 내가 없 충돌?
유닉스 소켓 스트림 모드 설명서를 우리에게는 추상 이름이 지정됩에서 그들을 connect
시간다면 그들은 이미 하나를 가지고 있지 않다면.는 이러한 기능을 사용할 수 있는 데이터그램 소켓 지향?
해결책
나는 가정을 실행하고 있는 Linux;내가 알지 못하는 경우 이러한 조언이 적용됩 SunOS 또는 어떤 유닉스.
첫 번째,응답:후에는 socket()및 전 connect()또는 첫 번째 sendto(),를 추가하려고 이 코드:
struct sockaddr_un me;
me.sun_family = AF_UNIX;
int result = bind(fd, (void*)&me, sizeof(short));
지금 설명:이 유닉스(7) 남자 페이지를 말한다:
때 소켓이 연결되어 있고 그것은 가 없는 로컬 주소 독특한 주소에서 추상 네임스페이스에 생성됩 자동으로 합니다.
슬프게도,남자 페이지의 거짓말입니다.
검사 소스 코드를 리눅스, 우리는 unix_dgram_connect()호출 unix_autobind()경우 SOCK_PASSCRED 에서 소켓 플래그입니다.하지 않기 때문에 나는 무엇을 알고 SOCK_PASSCRED,그리고 그것은 지금 1:00am,나를 찾을 필요가 다른 솔루션입니다.
검사 unix_bind, 나머지 unix_bind 전화 unix_autobind 경우에는 전달에서 크기는"sizeof(short)".따라서,위의 솔루션.
운이 좋은,그리고 좋은 아침입니다.
Rob
다른 팁
이 유닉스(7) 남자 페이지 내가 참조했고 이에 대한 정보를 autobind 유닉스 소켓:
는 경우 바인딩(2)호출을 지정합 addrlen 로 sizeof(sa_family_t),또는 SO_PASSCRED 소켓 옵션이 지정되었는 소켓적으로 행하는 주소,그 소켓 autobound 를 추상적인 주소입니다.
이런 이유는 리눅스 커널에 주소를 확인합의 길이는 동등한 sizeof(short)기 때문에 sa_family_t 은 짧습니다.기타 유닉스(7)맨페이지를 참조하여 강탈의 위대한 대답을 말한다는 소켓 클라이언트는 항상 autobound 에 연결지만,때문에 SOCK_DGRAM 소켓 연결 없음(에도 불구하고 전화 연결이 그들에이)나는 이것을 믿을만 적용됩니다 SOCK_STREAM 소켓이 있습니다.
또한 경우에는 공급하는 당신의 자신의 추상적인 네임스페이스 소켓 이름,소켓의 주소에서 이 네임스페이스에 의해 주어 추가적인 바이트 sun_path 적용되는 지정된 길이의 주소는 구조입니다.
struct sockaddr_un me;
const char name[] = "\0myabstractsocket";
me.sun_family = AF_UNIX;
// size-1 because abstract socket names are not null terminated
memcpy(me.sun_path, name, sizeof(name) - 1);
int result = bind(fd, (void*)&me, sizeof(me.sun_family) + sizeof(name) - 1);
sendto()한 마찬가지로 제한 주소로 길이,그리고 전달하지 않 sizeof(sockaddr_un).
조금 늦게 응답하지만,누구에게나 찾아 이를 사용하여 google 로 했습니다.Rob 아담의 대답이 나에게는'진짜'응답이:단순히 설정을 사용하여(준 SO_SOCKET
, 참조하십시오 man 7 unix
용)정 SO_PASSCRED
1.가 필요없는 바보할 수 있습니다.
내가 사용하는 이 PHP 에서지만,그것은 필요가 없 SO_PASSCRED
정의(보 PHP).그것은 여전히 작동하는 경우에,그러나 당신이 그것을 정의한다.내 컴퓨터에 있는 16 의 값,그리고 나는 생각한 것을 매우 portably.
내가 정말 잘 모르겠어요 이해 당신의 질문에 완전히지만,여기에는 데이터그램의 구현하는 echo 서버 난 그냥 밝혔다.당신이 볼 수 있는 서버의 응답을 클라이언트와 동일한 IP/포트로 전송되었습니다.
여기에는 코드
첫번째 서버(수신기)
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()
이제,클라이언트(sender)을 받는 응답 수신기
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