W przypadku pracy domowej muszę utworzyć program klienta / serwera, aby przechowywać dane. Klient odczytuje plik i wysyła go do serwera przez gniazdo, serwer otrzymuje go i przechowuje dane. Ostatecznym celem jest wdrożenie rzucania między kilkoma serwerami. Program działa dobrze, ale funkcja odczytu zawsze odczytuje mniej danych niż poprosiłem, gdy klient i serwer nie znajdują się w tej samej maszynie

Oto mój kod do czytania:

static inline size_t reliableRead(const int sourceSocket, void* data, const size_t nBytes)
{
    size_t dataRead = 0;
    unsigned int lossInARaw = 0;

    do
    {   const size_t readStatus = read(sourceSocket,data+dataRead,nBytes - dataRead);

        if (readStatus == (unsigned)-1)
        {
            LOG_ERRNO_ERROR("error on read");
            break;
        }

        dataRead += readStatus;

        if (readStatus != nBytes)
            LOG_WARNING("data loss(%u): read %zu/%zuo",++lossInARaw,dataRead,nBytes);
    } while (dataRead < nBytes);

    return dataRead;
}

Oto wynik, gdy próbuję przeczytać bloki 1024O, a następnie 8192o. Pierwszy klient i serwer są dwoma hostami różnicowymi, a następnie na tym samym

Serwer po stronie podczas odbierania danych pokrojonych w blokach 1024O od klienta na innej maszynie Wprowadź opis obrazu tutaj

Serwer po stronie podczas odbierania danych pokrojonych w blokach 8192O od klienta na innej maszynie Wprowadź opis obrazu tutaj

Serwer po stronie podczas odbierania danych, gdy klient jest również na maszynie Wpisz opis obrazu tutaj

Z obrazu, czytaj jest wyraźnie zdolny do czytania więcej niż 1024o. Nigdy wcześniej nie można tego zrobić, więc może coś brakuje, jak mogę sprawić, by funkcja odczytu czytała Mor często ilość danych, o których zadałem czytać? Ponieważ nawet bez wyświetlania ostrzeżenia, to wyraźnie zwiększa czas wysyłania (nie przeszkadza w tym czasie Messag, jest wyraźnie wyłączone, będę pracował nad tym)

6
Adrien 17 październik 2020, 20:08

1 odpowiedź

Najlepsza odpowiedź

Dla recv, a nie read, POSIX określa MSG_WAITALL Flaga, które powinieneś być w stanie użyć, aby zapobiec niepotrzebnym kontekstom przełączać się do wątku, gdy wszystko będzie tylko ponowne poprosić o pozostałą część bywalka-częściowego read .

MSG_WAITALL na gniazdach Sock_stream Zaprasza, że blok funkcyjny do czasu zwrócenia pełnej ilości danych. Funkcja może zwrócić mniejszą ilość danych, jeśli gniazdo jest gniazdo oparte na wiadomości, jeśli sygnał zostanie złapany, jeśli połączenie zostanie zakończone, jeśli określono MSG_PEEK lub jeśli błąd jest w oczekiwaniu na gniazdo.

5
PSkocik 18 październik 2020, 07:16