2012-12-12 23 views
5

Wykonuję jedno nieblokujące wysyłanie połączenia na jednym gnieździe, a następnie blokowanie w innym gnieździe. Następnie chcę sprawdzić, czy wysłanie nieblokujące się powiodło lub się nie udało. Jak to zrobić?Sprawdź, czy wysłanie nie blokujące się powiodło.

while (i) 
    { 
     retval = send (out_sd, s_message, strlen (s_message), MSG_DONTWAIT); 
     retval = recv (client_sd, r_message, MSG_LEN, 0); 
     r_message[retval] = '\0'; 
     /* Here I want to wait for the non-blocking send to complete */ 
     strcpy (s_message, r_message); 
     strcpy (r_message, ""); 
     i--; 
    } 
+0

Czy można skorzystać z oddzwonienia? – andre

+1

Nie sądzę. Wystarczy sprawdzić, czy wysłanie wiadomości nie powiodło się lub powiodło się, lub w kolejce, przed przejściem do następnej iteracji. – phoxis

+0

Użyj dwóch różnych var/s do przechowywania wyników wysyłania/recv do. – alk

Odpowiedz

5

Ty jakoś mieszania synchronicznych i asynchronicznych IO, który jest zwykle nieco mylące, ale nie widzę żadnego praktycznego problemu tutaj.

Aby uniknąć twardego pobierania (które sprawdza, czy operacja zakończyła się pętlą), należy użyć opcji select(), aby poczekać na udostępnienie kanału/gniazda, aby uzyskać więcej operacji zapisu. Powiedziałoby ci to, że poprzedni został ukończony (lub że został całkowicie przejęty przez twój system operacyjny, który jest taki sam).

Funkcja select() jest podstawą dla asynchronicznego IO w C, powinieneś przeczytać o tym w here, a this jest przykładem, który moim zdaniem może ci się przydać.

Zwróć uwagę, że select() obsługuje zdarzenia odczytu, zapisu i wyjątku, przykład pokazuje odczyt wybierz, chcesz zrobić zaznaczenie zapisu.

+0

Tak, mam mieszane synchroniczne i asynchroniczne I/O, ale w różnych gniazdach, myślę, że to będzie działać dobrze. Każdy proces wykona ten fragment kodu, dlatego jeśli oba będą blokować, wystąpi zakleszczenie. Dlatego najpierw wysyłam wiadomości, a następnie czekam na odbiór. Gdy jeden proces otrzyma dane, powinien sprawdzić, czy ostatnie niepowodzenie blokowania zakończyło się sukcesem przed wejściem do kolejnej iteracji. – phoxis

+1

Nie znam szczegółów, ale jeśli oba gniazda łączą te same 2 programy, czy na pewno nie można po prostu użyć połączeń synchronicznych? Podobnie jak program A wykonuje READ -> WRITE -> READ -> itd., A program B wykonuje WRITE -> READ -> WRITE -> itd. Jest to robione zwykle i nie ma w nim zakleszczenia. –

+0

Tak, istnieje możliwość zmiany naprzemiennego odczytu i zapisu, ale chcę tego uniknąć. – phoxis

1

send() zwróci liczbę wysłanych bajtów lub -1 w przypadku błędu.

Jeśli w stosie sieci jest wystarczająca ilość buforu, aby wysłać co najmniej kilka bajtów z wiadomości, to retval będzie zawierać liczbę wysłanych bajtów, która może być mniejsza niż liczba bajtów, które chcesz wysłać. Jeśli bufor stosu sieciowego jest pełny, będzie zawierał -1 i errno zostanie ustawiony na EAGAIN lub EWOULDBLOCK.

We wszystkich przypadkach wysyłanie jest zakończone natychmiast po powrocie. Nie musisz więc czekać na zakończenie wysyłania wiadomości bez blokowania, musisz sprawdzić wartość zwracaną zaraz po zwróceniu wywołania send().

Powiązane problemy