В следующем, у клиента есть небольшая вероятность получить «сломанную трубу», когда он пытается объединить, несмотря на то, что гнездо, насколько я вижу, открывается. («Маленький шанс», по -видимому, зависит от различных факторов, включая, помимо прочего, системную нагрузку.) < /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
Сплайсинг от stdin до гнезда: сломанная труба ⇐ Linux
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Почему я сталкиваюсь с [Errno 32] Сломанная труба, когда запускаю новый процесс?
Anonymous » » в форуме Python - 0 Ответы
- 20 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Почему я сталкиваюсь с [Errno 32] Сломанная труба, когда запускаю новый процесс?
Anonymous » » в форуме Python - 0 Ответы
- 23 Просмотры
-
Последнее сообщение Anonymous
-