2015-06-13 15 views
5

Mam serwer napisany w języku C++, który tworzy i łączy się z abstrakcyjnym gniazdem unix o adresie przestrzeni nazw "\0hidden". Mam również klienta, który jest napisany w języku C++ również i ten klient może pomyślnie połączyć się z moim serwerem. BTW, nie mam kodu źródłowego tego klienta. Teraz próbuję połączyć się z moim serwerem za pomocą klienta, który napisałem w Pythonie bez powodzenia. Nie rozumiem, dlaczego mój klient Pythona nie działa. Publikuję odpowiednie części mojego serwera i kody klientów.Nie można połączyć się z abstrakcyjnym gniazdem unix w pythonie

Server

#define UD_SOCKET_PATH   "\0hidden" 
struct sockaddr_un addr; 
int fd,cl; 

if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
{ 
    syslog(LOG_CRIT, "Error creating socket!"); 
    exit(1); 
} 

memset(&addr, 0, sizeof(addr)); 
addr.sun_family = AF_UNIX; 
strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1); 
unlink(UD_SOCKET_PATH); 


if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) 
{ 
    syslog(LOG_CRIT, "Bind error"); 
    exit(1); 
} 

if (listen(fd, MAX_CONN_PENDING) == -1) 
{ 
    syslog(LOG_CRIT, "Listen error"); 
    exit(1); 
} 

syslog(LOG_INFO, "Start listening."); 

A mój kod klienta

#! /opt/python/bin/python 
import os 
import socket 
import sys 
# Create a UDS socket 
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 

server_address = "\0hidden" 
print >>sys.stderr, 'connecting to %s' % server_address.decode("utf-8") 
try: 
    sock.connect(server_address) 
except socket.error, msg: 
    print >>sys.stderr, msg 
    sys.exit(1) 

Po uruchomieniu klient otrzymuję następujący komunikat o błędzie:

connecting to hidden 
[Errno 111] Connection refused 

I przez jakiś dodatkowych informacji jestem delegowania odpowiednie części wyjść strace mojego działającego klienta C++ i niepracującego klienta Pythona:

Praca C++ klient:

socket(PF_FILE, SOCK_STREAM, 0)   = 3 
connect(3, {sa_family=AF_FILE, [email protected]""}, 110) = 0 
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d7000 
write(1, "Sent message is: 00014 www.googl"..., 38) = 38 
write(3, "00014 www.google.com", 20) = 20 
recv(3, "014 Search Engines", 99, 0) = 18 
write(1, "014 Search Engines\n", 19) = 19 
close(3)        = 0 
exit_group(0)       = ? 

Żaden pyton działa klient:

socket(PF_FILE, SOCK_STREAM, 0)   = 3 
connect(3, {sa_family=AF_FILE, [email protected]"hidden"...}, 9) = -1 ECONNREFUSED (Connection refused) 
write(2, "Traceback (most recent call last"..., 35) = 35 
write(2, " File \"./uds.py\", line 13, in <"..., 40) = 40 
open("./uds.py", O_RDONLY|O_LARGEFILE) = 4 
fstat64(4, {st_mode=S_IFREG|0755, st_size=839, ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000 
read(4, "#! /opt/python/bin/python\nimport"..., 4096) = 839 
write(2, " ", 4)      = 4 
write(2, "sock.connect('\\0hidden')\n", 25) = 25 
close(4)        = 0 
munmap(0xb7792000, 4096)    = 0 
write(2, " File \"/opt/python/lib/python2."..., 64) = 64 
open("/opt/python/lib/python2.7/socket.py", O_RDONLY|O_LARGEFILE) = 4 
fstat64(4, {st_mode=S_IFREG|0755, st_size=20234, ...}) = 0 
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000 
read(4, "# Wrapper module for _socket, pr"..., 4096) = 4096 
read(4, "oo long.\"\n errorTab[10064] = "..., 4096) = 4096 
write(2, " ", 4)      = 4 
write(2, "return getattr(self._sock,name)("..., 39) = 39 
close(4)        = 0 
munmap(0xb7792000, 4096)    = 0 
write(2, "socket", 6)     = 6 
write(2, ".", 1)      = 1 
write(2, "error", 5)     = 5 
write(2, ": ", 2)      = 2 
write(2, "[Errno 111] Connection refused", 30) = 30 
write(2, "\n", 1)      = 1 
rt_sigaction(SIGINT, {SIG_DFL, [], 0}, {0x810fbe0, [], 0}, 8) = 0 
close(3)        = 0 
exit_group(1)       = ? 

A także, gdy uruchomię mój C++ klient, dostaję to wyjście strace z mojego serwera:

0, NULL)      = 12 
futex(0x80646a4, FUTEX_CMP_REQUEUE_PRIVATE, 1, 2147483647, 0x8064688, 360) = 10 
futex(0x8064688, FUTEX_WAKE_PRIVATE, 1) = 1 
accept(5, 

Ale kiedy uruchamiam mojego klienta Pythona, w Strace nie są wyświetlane żadne dane wyjściowe. Wygląda na to, że próbuję połączyć się ze złym adresem, ale mój adres jest zdefiniowany jako "\0hidden" zarówno na moim serwerze, jak i na moim kliencie.

+0

Dwie ścieżki łączenia w wyjściach strace są ** NIE ** takie same. Ogłoszenie? –

+0

Tak, zrobiłem. Nie wiem, dlaczego są inne. W C++ wygląda na pusty, co jest dziwne. Ale w kodzie serwera jest wyraźnie zdefiniowany jako "\ 0hidden". Jakieś pomysły? – Alptugay

Odpowiedz

3

Twoje C++ nie robi dokładnie tego, co myślisz, że robi. Ta linia:

strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1); 

Kopiuje jeden znak null '\0' do addr.sun_path. Uwaga ten wiersz w manpage dla strncpy():

Jeżeli długość src jest mniejsza niż n, strncpy() zapisuje dodatkowa null bajtów do dest aby upewnić się, że w sumie n bajtów są napisane.

W rezultacie twoje C++ faktycznie łączy się z gniazdem abstrakcyjnej domeny pod numerem "\0". Python robi to dobrze i łączy się z gniazdem abstrakcyjnej domeny pod adresem "\0hidden".

+0

Tak, wydaje się, że jest to problem. Dzięki – Alptugay

Powiązane problemy