mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2026-10-11 19:14:30 +00:00
make send file accept a non-blocking socket
This commit is contained in:
+31
-8
@@ -1108,17 +1108,40 @@ void TNetwork::SendFileToClient(TClient& c, size_t Size, const std::string& Name
|
|||||||
// native handle, needed in order to make native syscalls with it
|
// native handle, needed in order to make native syscalls with it
|
||||||
int socket = c.GetTCPSock().native_handle();
|
int socket = c.GetTCPSock().native_handle();
|
||||||
|
|
||||||
ssize_t ret = 0;
|
const auto ToSendTotal = Size;
|
||||||
auto ToSendTotal = Size;
|
size_t TotalSent = 0;
|
||||||
auto Start = 0;
|
while (TotalSent < ToSendTotal) {
|
||||||
while (ret < ssize_t(ToSendTotal)) {
|
off_t SysOffset = off_t(TotalSent);
|
||||||
auto SysOffset = off_t(Start + size_t(ret));
|
const ssize_t SentNow = sendfile(socket, fd, &SysOffset, ToSendTotal - TotalSent);
|
||||||
ret = sendfile(socket, fd, &SysOffset, ToSendTotal - size_t(ret));
|
if (SentNow > 0) {
|
||||||
if (ret < 0) {
|
TotalSent += size_t(SentNow);
|
||||||
beammp_errorf("Failed to send mod '{}' to client {}: {}", Name, c.GetID(), std::strerror(errno));
|
continue;
|
||||||
|
}
|
||||||
|
if (SentNow == 0) {
|
||||||
|
beammp_errorf("Failed to send mod '{}' to client {}: sendfile returned 0 before all bytes were sent", Name, c.GetID());
|
||||||
|
::close(fd);
|
||||||
|
DisconnectClient(c, "sendfile returned 0 during mod download");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (errno == EINTR) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (errno == EAGAIN
|
||||||
|
#if EWOULDBLOCK != EAGAIN
|
||||||
|
|| errno == EWOULDBLOCK
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
beammp_errorf("Failed to send mod '{}' to client {}: {}", Name, c.GetID(), std::strerror(errno));
|
||||||
|
::close(fd);
|
||||||
|
DisconnectClient(c, "sendfile failed during mod download");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
::close(fd);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
std::ifstream f(Name.c_str(), std::ios::binary);
|
std::ifstream f(Name.c_str(), std::ios::binary);
|
||||||
|
|||||||
Reference in New Issue
Block a user