Witam.
Robię program łączący się z serwerem POP3. Nie bardzo wiem jak mogę sprawdzić, czy cały czas mam połączenie z serwerem. W swoim programie łączę się z serwerem (wysyłam login, hasło...). Teraz między tym momentem a kolejnymi operacjami może minąć sporo czasu. Jak mam sprawdzić, czy w międzyczasie serwer się ze mną nie pożegnał? Muszę wiedzieć, że straciłem połączenie, żeby w razie konieczności móc powtórzyć sekwencję logowania. Niestety, próbowałem różnych metod i nic nie działa.
Ma ktoś jakiś pomysł?
Po pierwsze lekkim bez sęsem jest łączyć się z serwerem następnie logować się na nim i później czekać - bo na co tu czekać ? odbierasz maile które są na skrzynce i się wylogowujesz. Schemat wygląda bardzo prosto i nie spotkałem się z klientem który by działał inaczej niż: logowanie - odbiór (jeśli coś jest) - wylogowanie.
Po drugie czy połączenie padło czy też nie dowiesz się przy np. odczycie danych. Funkcja recv zwraca 0 jeśli połączenie zostało zakończone lub -1 jeśli wystąpił błąd (co w konsekwencji też daje zakończone połączenie).
deyot na 100 pro używa blokującego socketa, dlatego nie wie nic o powiadomieniach.
recv wywoane ot tak, zablokuje mu wątek, póki serwer go rozłączy lub coś łaskawie wyśle.
Zato send() z zerową ilością danych zwróci zero (połączony) lub -1 w razie braku połączenia, nie blokując wątku.
Witam.
Dzięki za szybką odpowiedź.
W sumie może i tak powinienem był robić ale i tak chciałbym wiedzieć jak sprawdzić skutecznie, czy mam połączenie. Obecnie mam mniej więcej taki kod:
memset(Buf, 0, DefBufSize);
strcat(Buf, "STAT\r\n");
int iret = send(Sock, Buf, strlen(Buf), 0);
if (iret>0) {
memset(Buf, 0, DefBufSize);
iret = recv(Sock, Buf, DefBufSize, 0);
};
if (iret==0 || iret==SOCKET_ERROR) {
iret = connect(Sock, (SOCKADDR*)&AddressData, sizeof(AddressData));
if (iret == SOCKET_ERROR) return 0;
....
Problem w tym, że w momencie próby kolejnego połączenie w razie wykrycia jego zakończenia lub braku połączenia (to znaczy jeżeli send() zwróci mi 0 albo SOCKET_ERROR albo recv() zwróci mi 0 lub SOCKET_ERROR ) zawsze otrzymuję SOCKET_ERROR. Nie mogę się ponownie połączyć i to jest teraz mój największy problem "iret = connect(Sock, (SOCKADDR*)&AddressData, sizeof(AddressData));" zawsze zwraca mi SOCKET_ERROR. Co muszę zrobić?
EDIT:
Właśnie zauważyłem, że pomaga jeśli przed wywołaniem connect() zamknę gniazdo. Proszę o wyjaśnienie, czy zawsze w takich przypadkach muszę robić tak: "otwieram gniazdo - robię swoje - zamykam gniazdo". Myślałem, że wystarczy jeżeli otworzę gniazdo na początku działania programu a na zamknę przy wyjściu. Jak to jest?
jesli wczesniejszy send(sock lub recv(sock zauwaza ze polaczenie jest zerwane, to to jest juz koniec zycia socketa. nie mozna go 'wskrzesic' wolaniem kolejnych connectow. usun socketa (shutdown+close), utworz nowego, i dopiero jego connectuj