Я пытаюсь написать программу, которая читает либо из сокета, либо из стандартного ввода. Если сокет, то выведите на стандартный вывод (пользователю), иначе выведите на сокет. До сих пор я использую poll
для пробуждения программы, когда есть активность, либо моя проблема заключается в том, что после первоначального подключения poll
всегда сообщает об активности в сокете, даже если клиент больше ничего не писал.
Есть ли способ отличить guish между "кто-то подключился к сокету" и "кто-то разместил сообщение на канале"? Просматривая справочные страницы для poll
, select
и других, я действительно не вижу соответствующего флага.
Если нет соответствующего флага, каков будет способ достижения sh того, что я ' я пытаюсь сделать?
То, что у меня сейчас есть, выглядит примерно так. Когда я вписываю что-то в стандартный ввод, возвращается poll
, и l oop определяет, что активность была в сокете (неправильно).
edit: Есть и другие проблемы, но я борюсь с этим прямо сейчас.
/* blocking accept for first and only connection */
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
/* poll stdin and newsockfd */
struct pollfd fds[2];
fds[0].fd = STDIN_FILENO;
fds[0].events = POLLIN;
fds[1].fd = newsockfd;
fds[1].events = POLLIN;
ioctl(newsockfd, FIONBIO, (char *)&on); /* int on = 1 */
while (1) {
int rc = poll(fds, 2, -1);
if (rc <= 0)
exit(1);
for (int i = 0; i < 2; i++) {
if (fds[i].revents == 0)
continue;
if (fds[i].revents != POLLIN)
exit(1);
if (fds[i].fd = newsockfd) {
n = read(newsockfd, buffer, 255);
printf("read %d chars from newsockfd: %s\n", n, buffer);
} else if (fds[i].fd = STDIN_FILENO) {
read(STDIN_FILENO, buffer, 255);
n = dprintf(newsockfd, "%s", buffer);
printf("wrote %d chars to newsockfd: %s\n", n, buffer);
}
}
}