Доброго времени!Столкнулся со странной проблемой. Создаю файловый сокет без путей (т.е. в текущей папке программы) - всё отлично работает. Создаю оный в папке /tmp клиент его не видит и всё тут. Вот код:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>#define SOCK_NAME "/tmp/socket.soc" // <<<<< меняю на "socket.soc" - работает
#define BUF_SIZE 256int main(int argc, char ** argv)
{
struct sockaddr srvr_name, rcvr_name;
char buf[BUF_SIZE];
int sock;
int namelen, bytes;
sock = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sock < 0){
perror("socket failed");
return EXIT_FAILURE;
}
srvr_name.sa_family = AF_UNIX;
strcpy(srvr_name.sa_data, SOCK_NAME);
namelen = strlen(srvr_name.sa_data) + sizeof(srvr_name.sa_family) + 1;
printf("Socket %s, namesize %i\n", srvr_name.sa_data, namelen);
unlink(SOCK_NAME);
if(fork()==0){
if (bind(sock, &srvr_name, namelen) < 0){
perror("bind failed");
return EXIT_FAILURE;
}
bytes = recvfrom(sock, buf, sizeof(buf), 0, &rcvr_name, &namelen);
if (bytes < 0) {
perror("recvfrom failed");
return EXIT_FAILURE;
}buf[bytes] = 0;
rcvr_name.sa_data[namelen] = 0;
fprintf(stdout, "Client sent: %s\n", buf);
unlink(SOCK_NAME)<0;
close(sock);
}
else{
char *mes = "Hello";
if(sendto(sock, mes, strlen(mes), 0, &srvr_name, namelen)<0)perror("Can't send");
}
}Естественно, клиент в другой программе, это я для компактности (и проверки) слил в одну (но в разные процессы). Клиент, по сути, выглядит также, только без bind. Ошибку выдаёт sendto, говорит, нету такого файла.
Ещё одно странное замечание. Если клиент и сервер в одном процессе, то работают нормально (т.е. если написать sendto прямо перед recvfrom). Т.о. как я понимаю, в папке /tmp не находит сокет-файл лишь другой процесс. Если клиент в другой программе, но в тойже папке, то всё работает.
Конечно, и вариант с размещением сокета в той же папке, что и программа, подходит, но как-то корректнее использовать /tmp.
Буду очень признателен за помощь.
Кстати, если скопировать клиента в /tmp и там запустить (а в самом клиенте название сокета без путей конечно), то работает.Т.е. клиент, почему-то не хочет работать с сокетом вне своей папки.
>Кстати, если скопировать клиента в /tmp и там запустить (а в самом
>клиенте название сокета без путей конечно), то работает.
>
>Т.е. клиент, почему-то не хочет работать с сокетом вне своей папки.Дело не в папке.
Есть 2 путЯ решения проблемы (если не втыкать зачем нужен путь "/tmp/sock...bla bla").
1) поменять местами строки с объявлением переменных
struct sockaddr srvr_name, rcvr_name;
и
int sock;2) уменьщить "путь_до_сокета" ака SOCK_NAME до 14 байт
первый способ сработает или нет в зависимости от архитектуры и (или) компилятора.(не правильный)
второй способ надеется на то, что sizeof(sockaddr) = 16
т.е.
sizeof(srvr_name.sa_family) = 2 (т.е. короткое целое без знака)
и sizeof(srvr_name.sa_data) = 14 (14 буковок)