Przeprowadzam testy z gniazdami domeny Unix i mogę komunikować się z nimi bez problemu, jednak gdy zadzwonię pod numer accept()
po stronie serwera mojego programu testowego, zwrócony struct sockaddr_un
nie zawiera sun_path
.Unixowe gniazda domen: accept() nie ustawia ścieżki sun_path
Jestem prawie pewien, że gniazda Inet mają prawidłowo wypełniony adres i port po rozmowie accept()
, więc czy robię coś nie tak w moim programie testowym lub czy oczekuję złego wyniku?
Używam CentOS 6.2 i gcc 4.4.6.
KodPróbka:
server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define NAME "socket"
int main(int argc, char **argv)
{
int sock, msgsock, rval;
struct sockaddr_un server, client;
char buf[1024];
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("opening stream socket");
exit(1);
}
server.sun_family = AF_UNIX;
strcpy(server.sun_path, NAME);
if (bind(sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un))) {
perror("binding stream socket");
exit(1);
}
printf("Socket has name %s\n", server.sun_path);
listen(sock, 5);
for (;;) {
socklen_t len = sizeof(client);
msgsock = accept(sock, (struct sockaddr *)&client, &len);
if (msgsock == -1)
perror("accept");
else do {
printf("strlen(sun_path) = %zu\n", strlen(client.sun_path));
bzero(buf, sizeof(buf));
if ((rval = read(msgsock, buf, 1024)) < 0)
perror("reading stream message");
else if (rval == 0)
printf("Ending connection\n");
else
printf("-->%s\n", buf);
} while (rval > 0);
close(msgsock);
}
close(sock);
unlink(NAME);
return 0;
}
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define DATA "Half a league, half a league . . ."
int main(int argc, char **argv)
{
int sock;
struct sockaddr_un server;
if (argc < 2) {
printf("usage:%s <pathname>", argv[0]);
exit(1);
}
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("opening stream socket");
exit(1);
}
server.sun_family = AF_UNIX;
strcpy(server.sun_path, argv[1]);
if (connect(sock, (struct sockaddr *) &server,
sizeof(struct sockaddr_un)) < 0) {
close(sock);
perror("connecting stream socket");
exit(1);
}
if (write(sock, DATA, sizeof(DATA)) < 0)
perror("writing on stream socket");
close(sock);
return 0;
}
Wystarczy powtórzyć pytanie:
Dlaczego nie sun_path
jest wypełniony po accept()
zadzwoń na serwer?
Naprawdę cud ... 'len' staje się' 2', który jest "sizeof (sa_family_t)" i według człowieka może się to zdarzyć tylko wtedy, gdy gniazdo jest niezwiązane, ale w twoim przypadku jest wyraźnie związane ... – kirelagin
Próbowałem też z abstrakcyjnymi gniazdami i znowu ta długość zawsze jest "2", co jest oczywiście błędne, zgodnie ze stroną podręcznika. – kirelagin
Myślę, że to może być normalne. Podobnie jak gniazda zwrócone przez 'socketpair()', tego typu gniazda nie są powiązane z żadną ścieżką, ale mimo to są podłączone do innego gniazda na drugim końcu. – Celada