|
|
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Проверяю состояние сокета через WaitForData. Я, конечно же, прочитал коммент, что Код: pascal 1. в связи с чем, возникает вопрос - как определить, что сокет уже "не живой"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 11:03 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
и чтобы без таймаута. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 11:05 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Cobalt747в связи с чем, возникает вопрос - как определить, что сокет уже "не живой"? Рекомендую иногда заглядывать на SO, там можно найти уже готовые ответы на многие вопросы: https://stackoverflow.com/questions/685951/how-can-i-check-if-a-client-disconnected-through-winsock-in-c if you call recv in blocking mode and it returns with 0 bytes read, the socket has disconnected, else it wait for bytes to be received. Т.е. если вы после WaitForData смогли прочитать только 0 байт или recv вернул SOCKET_ERROR с ошибкой WSAECONNRESET, то сокет был закрыт. Разные результаты, как я понимаю, зависят от того как именно было закрыто соединение: тупо разорвана связь или именно "закрыто" другой стороной (насчёт последнего я, правда, не уверен на 100%, необходимо проверять). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 11:36 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
В том-то и дело, что хочу избежать такой ситуации: авторelse it wait for bytes to be received. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 12:01 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
alekcvpТ.е. если вы после WaitForData смогли прочитать только 0 байт или recv вернул SOCKET_ERROR с ошибкой WSAECONNRESET, то сокет был закрыт Я так понимаю, что WaitForData - это select. И если он вернет 0, и recv не вернет SOCKET_ERROR, то он повиснет намертво, пока не прочитает то, что надо. Правда, не знаю, что будет, если передать в recv длину 0. Скорее всего, он всегда сразу будет возвращать 0, это логично. Речь о блокирующих сокетах. Cobalt747как определить, что сокет уже "не живой"? Это делается с помощью select. Вот что-то подобное: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. Ну и вот: 1. Если WaitForData вернула > 0 - значит есть данные для чтения; 2. Если WaitForData вернула = 0 - значит нет данных для чтения, но сокет "живой" ; 3. Если WaitForData SOCKET_ERROR - значит всё, можешь вызывать WSAGetLastError/SysErrorMessage, если надо. И, конечно, сокет может умирать далеко не сразу. Может через десятки секунд, минуты (после того, как где-то шнурок перетыкнут). А ты говоришь, без таймаута. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 13:23 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Да, и если WaitForData вернул > 0, то recv потом тоже может SOCKET_ERROR вернуть - это тоже надо проверять. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 13:24 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Cobalt747В том-то и дело, что хочу избежать такой ситуации: авторelse it wait for bytes to be received. Я исходил из этого: If no error occurs, recv returns the number of bytes received and the buffer pointed to by the buf parameter will contain this data received. If the connection has been gracefully closed, the return value is zero . .... For connection-oriented sockets (type SOCK_STREAM for example), calling recv will return as much data as is currently available—up to the size of the buffer specified. Т.е. предполагается, что если select (WaitForData) показал наличие данных для чтения, то и первый после него вызов recv тоже не должен блокироваться. Что мешает проверить экспериментально? :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 13:36 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Cobalt747как определить, что сокет уже "не живой"? Никак. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 22:34 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Maxim RusovCobalt747как определить, что сокет уже "не живой"? Никак.Не, ну в общем случае, конечно, никак, но со временем эту информацию можно получить. Особенно, если логика построена таким образом, что либо recv постоянно висит, либо в промежутках между этими "висениями" send отправляет. Так мне больше всего ошибку получать нравится. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2017, 23:35 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
alekcvp, Это не та задача что передо мной стоит. Мне надо различать: 1) отсутствие данных от сервера 2) разрыв связи с сервером. Причем я не хочу висеть на коннекте, блокируя поток. Пока что вышел из положения, задав SO_RCVTIMEO ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2017, 10:27 |
|
||
|
сокет уже "не живой"
|
|||
|---|---|---|---|
|
#18+
Cobalt747alekcvp, Это не та задача что передо мной стоит. Мне надо различать: 1) отсутствие данных от сервера 2) разрыв связи с сервером. Причем я не хочу висеть на коннекте, блокируя поток. Ну так в чём проблема: сначала делаешь select с readfds, для проверки сокета. Если результат 0 - нет данных для чтения, если 1 - либо есть данные, либо дисконнект, если SOCKET_ERROR - значит ошибка. Во втором случае (select() = 1) делаешь recv() один байт с флагом MSG_PEEK, если он вернёт 0 или ошибку - значит дисконнект, если больше - значит есть данные для чтения. При этом данные никуда не денутся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.12.2017, 10:58 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39571859&tid=2041430]: |
0ms |
get settings: |
10ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
221ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 238ms |
| total: | 550ms |

| 0 / 0 |
