LINUX.ORG.RU

sendto No such file or directory

 


0

2

Есть такой вот отрезок кода

bytes_send=sendto(sock, &sms_length, sizeof(size_t), 0, &srvr_name,strlen(srvr_name.sa_data) + sizeof(srvr_name.sa_family));
  if(bytes_send < sizeof(size_t)){
    perror("Cannot write data to socket");
    return 1;
  }
  printf("%d bytes send\n", bytes_send);
  
  bytes_send=sendto(sock,argv[1],sms_length, 0, &srvr_name,strlen(srvr_name.sa_data) + sizeof(srvr_name.sa_family));
  printf("%d bytes send\n", bytes_send);
  if(bytes_send == -1){
    perror("Cannot write data to socket");
    return 1;
  }
Фишка в том, что первая sendto срабатывает на ура, байты уходят в сокет вполне успешно. А вот второй sendto заканчивается
Cannot write data to socket:No such file or directory.
На момент завершения работы программы файл сокета существует. Права тоже позволяют запись. На другой стороне между двумя симметричными recvfrom никаких операций над файлом не производится.

★★★

вызов printf между sendto и perror, видимо, меняет значение errno. Уберите этот printf, или восстанавливайте errno после него.

Krieger_Od ★★
()
Ответ на: комментарий от Krieger_Od

Убрал весь код между sendto, ничего не поменялось. По принимающей стороне вижу, что первая ф-ция отрабатывает, вторая вываливается. Значение sock в программе проверяется, оно корректное. Вот кстати весь код http://pastebin.com/UTSYvrK6

LIKAN ★★★
() автор топика

Фишка в том, что первая sendto срабатывает на ура

Фишка в том, что таки не срабатывает. Собери с ключом -Wsign-compare и почитай что тебе пишет gcc.

edigaryev ★★★★★
()
Ответ на: комментарий от anonymous

Что не так-то? В структуре заполнены два поля, значит размер структуры равен сумме длин полей, sa_data - char*. sa_family - что-то целочисленное.

LIKAN ★★★
() автор топика

вот объясни мне, барану, зачем в операции send указывать адрес, если ты указываешь дескриптор сокета, т.е. ты уже открыл сокет по этому адресу?

Чем функция sendto от send отличается?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

А в общих случаях и send нафиг не нужен (если ты флаги не передаешь) — тупо write вызывай.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от edigaryev

Я проверку же только ради вас закомментировал, мол printf сбивает код ошибки, а вот что с раскомментированным пишет

  $ ./sock_client "Hello"
8 bytes send
...
На -1 никак не похоже.

LIKAN ★★★
() автор топика

sizeof (struct sockaddr) == 16. Для 32 разрядных. Т.о. strcpy(srvr_name.sa_data, SOCK_NAME) - переполнение буфера, первый вызов sendto получает еще тепленький и целый путь к файлу, но в процессе работы портит его. Если хочешь убедиться, вставь

    printf ("%s\n", srvr_name.sa_data);
до и после первого sendto. Первый покажет правильный путь, а второй - мусор. Поэтому второй sendto получает мусор вместо имени файла. Отсюда и «no such file».

Для AF_UNIX нужен sockaddr_un:

    struct sockaddr_un srvr_name;
    srvr_name.sun_family = AF_UNIX;
    strcpy (srvr_name.sun_path, SOCK_NAME);
    sendto (,,,,&srvr_name, sizeof(struct sockaddr_un));

fopen ★★
()
Ответ на: комментарий от Eddy_Em

Вот что будет, если адрес не указать

-1 bytes send
-1 bytes send
Cannot write data to socket: Transport endpoint is not connected

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Правильно. Ведь ты не сделал connect. А, дошло до меня теперь, нафига ты пользуешься этой функцией!

Кстати, показал бы ты код, которым принимающий сокет открываешь. Может у тебя там косяк?

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от fopen
ошибка: размер «srvr_name» в памяти неизвестен

Заголовочник какой нужно подключить для _un структуры?

LIKAN ★★★
() автор топика
Последнее исправление: LIKAN (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

connect нужен для потоковых сокетов, а я хочу дейтаграммные. Тут товарищ fopen кажется оочень мудрые вещи говорит, я даже кажется в прошлой жизни сталкивался с тем что размер поля маловат.

LIKAN ★★★
() автор топика
Ответ на: комментарий от fopen

Окей.... но увы

предупреждение: в передаче аргумента 5 «recvfrom»: несовместимый тип указателя
...
амечание: expected «struct sockaddr * __restrict__» but argument is of type «struct sockaddr_un *»
нельзя sockaddr_un использовать.

LIKAN ★★★
() автор топика
Ответ на: комментарий от LIKAN

Да прочти ж ты доки. Можно. И нужно. sockaddr - это бызовый тип для всех видов адресов. Заполняешь нужный тебе тип адреса, преобразуешь указатель к базовому, и передаешь куда надо.

sendto (,,,,(struct sockaddr *) &srvr_name, sizeof(struct sockaddr_un));

fopen ★★
()
Ответ на: комментарий от Eddy_Em

Сделал-сделал. Уже все работает, благодаря телепатическим способностям товарища fopen.

LIKAN ★★★
() автор топика

Вопрос. Почему bytes send вместо bytes sent?

wakuwaku ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.