Подскажите пожалуйста хоть в какую сторону рыть, сутки проб и поисков не дали результата...
Пишу простенький веб-сервер сугубо для своих нужно, нужно отправлять и получать JSON.
Тестил в Firefox, все отлично, запустил на Webkit-подобном движке и...
Обнаружил что tcp пакет с хедером и контент с json идут в разных tcp пакетах! (суммарный размер прмиерно 300 байт и оно почему -то разбивает на 2 пакета!)
В Firefox, опять таки, такого нет. Один пакет.
Мой код с epoll просыпается когда есть данные на сокете, но считывается только хедер без данных...
Код работы с epoll в целом стандартный:
constexpr uint16_t EPOLL_SIZE {1024};
static struct epoll_event events[EPOLL_SIZE];
int sockfd {0};
int epoll_events_count {0};
struct sockaddr_in client_addr;
socklen_t socklen = sizeof(struct sockaddr_in);
epfd_ = epoll_create(EPOLL_SIZE);
ev_.data.fd = sockfd_;
ev_.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
epoll_ctl(epfd_, EPOLL_CTL_ADD, sockfd_, &ev_);
while (true) {
try {
process_loop();
unsigned int timeout = process_get_standby();
epoll_events_count = epoll_wait(epfd_, events, EPOLL_SIZE, timeout);
for (int n=0; n<epoll_events_count; n++) {
int fd = events[n].data.fd;
if (fd == sockfd_) {
sockfd = accept(sockfd_, (struct sockaddr *)&client_addr, &socklen);
if (sockfd < 0)
continue;
//tcout() << "[info] established connection from: " << inet_ntoa(client_addr.sin_addr) << ":" << ntohs(client_addr.sin_port) << ", socket: " << sockfd << std::endl;
uint32_t ip = ntohl(client_addr.sin_addr.s_addr);
uint16_t port = ntohs(client_addr.sin_port);
process_client_connect(sockfd, ip, port);
}
else {
if ((events[n].events & EPOLLERR) || (events[n].events & EPOLLHUP)) {
process_client_disconnect(fd);
continue;
}
else if (events[n].events & EPOLLIN || EPOLLPRI) {
process_data_received(fd);
}
}
}
}
catch (std::exception &e) {
*lgr << LogLevel::error << "[exception] in server class: " << e.what();
}
catch (...) {
*lgr << LogLevel::error << "[exception] in server class";
}
}
Код считывания с сокета, на котором есть данные:
нижеприведенный код создает буффер определенного размера, если считаны данный длинной с буффер — расширяем его еще и так пока считается меньше чем шаг буффера, потом ресайзим буффер
int32_t rv {0};
static constexpr uint32_t incoming_buffer_size {2048};
try {
buffer.clear();
do {
uint32_t current_position = buffer.size();
buffer.resize(buffer.size() + incoming_buffer_size);
rv = read(sockfd, buffer.data() + current_position, incoming_buffer_size);
*lgr << LogLevel::info << __func__ << " rv " << rv;
if (rv < 0) {
*lgr << LogLevel::error << __func__ << "() broken connection detected during read";
throw std::exception();
}
if ((rv < static_cast<int32_t>(incoming_buffer_size)) and (buffer.size() == incoming_buffer_size))
buffer.resize(rv);
else if (rv < static_cast<int32_t>(incoming_buffer_size))
buffer.resize(current_position + rv);
}
while (rv == static_cast<int32_t>(incoming_buffer_size));
}
catch (...) {
*lgr << LogLevel::error << __func__ << " exception";
return -1;
}
*lgr << LogLevel::info << __func__ << " buffer.size() " << buffer.size();
return buffer.size();
опция TCP_DEFER_ACCEPT не помогает, может она не для этого предназначена? вроде как должна
Тоесть мой код видит первый пакет и все, второй не видит. Wireshark говорит что пакет доставлен.
Запустил пример на асинхронном boost, тоже самое...
Подскажите пожалуйста