Сплайсинг от stdin до гнезда: сломанная трубаLinux

Ответить Пред. темаСлед. тема
Anonymous
 Сплайсинг от stdin до гнезда: сломанная труба

Сообщение Anonymous »

В следующем, у клиента есть небольшая вероятность получить «сломанную трубу», когда он пытается объединить, несмотря на то, что гнездо, насколько я вижу, открывается. («Маленький шанс», по -видимому, зависит от различных факторов, включая, помимо прочего, системную нагрузку.) < /P>
Я не уверен, почему это так. Если я правильно помню, Epipe дается при написании в дескриптор файла без прослушивателей. Еще более запутанно, как это происходит периодически. /p>
#include
#include
#include
#include
#include
#include

#define SOCKET_PATH "test.sock"

int main(void)
{
int server_fd, client_fd;
struct sockaddr_un addr;

server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (server_fd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}

memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);

if (bind
(server_fd, (struct sockaddr *)&addr,
sizeof(struct sockaddr_un)) == -1) {
perror("bind");
close(server_fd);
exit(EXIT_FAILURE);
}

if (listen(server_fd, 1) == -1) {
perror("listen");
close(server_fd);
exit(EXIT_FAILURE);
}

printf("Listening %s\n", SOCKET_PATH);

while (1) {
client_fd = accept(server_fd, NULL, NULL);
if (client_fd == -1) {
perror("accept");
close(server_fd);
exit(EXIT_FAILURE);
}

close(client_fd);
}

close(server_fd);
return 0;
}
< /code>
client.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

#define SOCKET_PATH "test.sock"

int main(void)
{
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
perror("signal");
return EXIT_FAILURE;
}

struct stat stdin_stat;
if (fstat(STDIN_FILENO, &stdin_stat) == -1) {
perror("fstat on stdin");
return EXIT_FAILURE;
}
if (!S_ISFIFO(stdin_stat.st_mode)) {
dprintf(STDERR_FILENO, "stdin must be a pipe\n");
return EXIT_FAILURE;
}
int stdin_pipe_size = fcntl(STDIN_FILENO, F_GETPIPE_SZ);
if (stdin_pipe_size == -1) {
perror("fcntl on stdin");
return EXIT_FAILURE;
}

int sock;
struct sockaddr_un addr;
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
perror("internal socket creation");
return EXIT_FAILURE;
}
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);
if (connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un))
== -1) {
perror("internal socket connect");
close(sock);
return EXIT_FAILURE;
}

ssize_t stdin_bytes_spliced;
while ((stdin_bytes_spliced =
splice(STDIN_FILENO, NULL, sock, NULL, stdin_pipe_size,
SPLICE_F_MORE)) > 0) {
}
if (stdin_bytes_spliced == -1) {
perror("splice stdin to internal socket");
close(sock);
return EXIT_FAILURE;
}

close(sock);
return EXIT_SUCCESS;
}
< /code>
Запуск: < /p>
#!/bin/bash

rm -f test.sock

cc -Wall -Wextra -Werror -pedantic -std=c99 -D_GNU_SOURCE server.c -o server
cc -Wall -Wextra -Werror -pedantic -std=c99 -D_GNU_SOURCE client.c -o client

./server &
server_pid="$!"

sleep 1 # give it time to start listening

counter=0
while true
do
echo "$counter"
head -c 512 /dev/zero | ./client || break
sleep 0.04
counter=$((counter + 1))
done

kill $server_pid
< /code>
(моя «реальная проблема» возникает в этом коде GO, но с момента обмена, это было бы трудно воспроизвести, я решил придумать минимальный рабочий пример в C и подтвердил, что Ошибочное поведение одинаково для MWE и фактического кода проекта.)


Подробнее здесь: https://stackoverflow.com/questions/794 ... roken-pipe
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Сплайсинг от stdin до гнезда: сломанная труба
    Anonymous » » в форуме Linux
    0 Ответы
    31 Просмотры
    Последнее сообщение Anonymous
  • Маним — BrokenPipeError: [Errno 32] Сломанная труба
    Anonymous » » в форуме Python
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • Android Studio — сломанная труба
    Anonymous » » в форуме Android
    0 Ответы
    25 Просмотры
    Последнее сообщение Anonymous
  • Почему я сталкиваюсь с [Errno 32] Сломанная труба, когда запускаю новый процесс?
    Anonymous » » в форуме Python
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • Почему я сталкиваюсь с [Errno 32] Сломанная труба, когда запускаю новый процесс?
    Anonymous » » в форуме Python
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Linux»