Получил некоторые проблемы с мультиплексированием сокетов TCP.TCP Socket Multiplexing Отправить большие данные
//socket is non-blocking
const int MAX = 4096;
char *buff[MAX];
char *p = buff;
int fd, rvalue;
rvalue = 0;
if ((fd = open(path, O_RDONLY)) < 0) {
return errno;
} else {
int didsend, didread;
int shouldsend;
while ((didread = read(fd, buff, MAX)) > 0) {
p = buff;
shouldsend = didread;
while (1) {
didsend = send(sockfd, p, shouldsend, 0);
//if send succeeds and returns the number of bytes fewer than asked for then try to send rest part in next time.
if (didsend < shouldsend) {
p += didsent;
shouldsend -= didsend;
continue;
}
//if there is no place for new data to send, then wait a brief time and try again.
if (didsend < 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) {
usleep(1000);
continue;
}
//if all data has been sent then sending loop is over.
if (didsend == shouldsend) {
break;
}
//send error
if (didsend < 0) {
rvalue = errno;
break;
}
}
}
close(fd);
if (didread == -1) {
return errno;
}
return rvalue;
}
Предположим, я использую I/O Multiplexing функция опроса() или Kqueue() и неблокируемой сокет, а затем, если есть только некоторые небольшие данные, как отправить короткое сообщение, он отлично работает.
Но если дело доходит до больших данных, я имею в виду больший размер буфера send(), поскольку с помощью неблокирующего сокета send() просто отправит часть данных и вернет, сколько данных он отправит, остальная часть данных может быть отправлена только в другом вызове send(), но требуется время и не может определить, сколько времени потребуется. Таким образом, второй while() на самом деле является блокирующей отправкой, которая использует неблокирующий сокет.
Эквивалент:
//socket is blocking
const int MAX = 4096;
char *buff[MAX];
int fd, n;
if ((fd = open(path, O_RDONLY)) < 0) {
return errno;
} else {
while ((n = read(fd, buff, MAX)) > 0) {
if (send(sockfd, buff, n, 0) < 0) {
return errno;
}
}
close(fd);
return 0;
}
Итак, что такое решение этой проблемы, многопоточность может работать, но это своего рода тратить ресурс может быть.
Будьте осторожны при выполнении 'while ((didread = read (fd, buff, MAX)))'. Помните, что 'read' возвращает' -1' при ошибке, а sinze '-1' отличен от нуля, считается« истинным ». Кроме того, если показанный код не находится в функции 'main', тогда у вас есть утечка ресурсов, так как вы не закрываете файл, который вы открываете. –
@JoachimPileborg Спасибо, я исправил его. – ryuu
that} else {для open, похоже, не добавляет значения –