URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 7209
[ Назад ]

Исходное сообщение
"Файловые сокеты"

Отправлено Mariupolets , 24-Фев-08 03:46 
Доброго времени!

Столкнулся со странной проблемой. Создаю файловый сокет без путей (т.е. в текущей папке программы) - всё отлично работает. Создаю оный в папке /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 256

int 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.

Буду очень признателен за помощь.


Содержание

Сообщения в этом обсуждении
"Файловые сокеты"
Отправлено Mariupolets , 24-Фев-08 03:52 
Кстати, если скопировать клиента в /tmp и там запустить (а в самом клиенте название сокета без путей конечно), то работает.

Т.е. клиент, почему-то не хочет работать с сокетом вне своей папки.



"Файловые сокеты"
Отправлено primus , 24-Фев-08 20:51 
>Кстати, если скопировать клиента в /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 буковок)