|
|
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
Имеются 2 приложения-службы, работающие по TCP-портам 49001 и 49002 (порты настраиваются). Используется TTCPBlockSocket из пакета Synapse. Код: 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. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. и клиентское приложение, общающееся с этими службами через указанные порты, в том числе регистрация этих сервисов, запуск и остановка Код: 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. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. Настройками предусмотрен также вариант работы без использования сокетов (по аналогии с командой sc), но в Windows10 для управления службами необходим запуск клиентской части от имени админа, что не устраивает безопасников. В общем, все это вполне работает, но беда в том, что к рабочему месту подключен фискальник, приложение работает с ним через COM-порт, но TCP также задействуется для работы в качестве онлайн-кассы (порт 7778). И через несколько часов работы фискальник начинает с завидным постоянством выпадать в ошибку -1 (Нет связи) именно на тех точках, где взаимодействие со службами ведется посредством TCP. Там где без TCP - проблем нет, специально менял режимы работы на одних и тех же точках. Вывод - что-то не так в приведенном коде, но что именно? (С сокетами работаю впервые, первоначальный код был заимствован из книги о Synapse Владислава Баженова, за что ему большое спасибо) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 08:58:29 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
P.S. SendString из клиентской части выполняется примерно раз в минуту, изначально параметр NeedConfirm всегда был True, сейчас планирую от этого уйти, но на проблемных точках еще не тестировал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 09:11:00 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaR, логирование же есть... Попробуй при ошибках дернуть GetLastError и WSAGetLastError. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 09:11:10 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
wadman, Так в самих сокетах ошибок нет - проблема в том, что они каким-то образом вышибают фискальник. А фискальник все что может сообщить - это ошибка -1 (Нет связи). Ну еще в его системном логе вот такие сообщения: TComPort ReadFile ERROR: 0x000003E3, Операция ввода/вывода была прервана из-за завершения потока команд или по запросу приложения. Я ему напрямую точно никаких команд на прерывание не выдаю, следовательно гадят работающие сокеты. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 09:40:22 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaR, утечки дескрипторов случайно нет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 09:44:39 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaR TComPort ReadFile ERROR: 0x000003E3, Операция ввода/вывода была прервана из-за завершения потока команд или по запросу приложения. Это проблема потока, где-то ошибка в нем. Оберни всё в try except и добавь логирование Exception. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 10:36:33 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
Если я правильно понял, то каждый раз при отправке строки (при NeedConfirm=True) будет заново устанавливаться соединение со службой. Если сокет уже подключен к серверу, зачем нужно его закрывать и подключаться снова? По поводу ошибки фискальника. Может быть количество открытых соединений косвенно влияет на его работу? Например, как уже писали выше про утечку дескрипторов. Если попробовать во время проблем с фискальником проверить в системе количество открытых сетевых соединений? Службам для обмена нужны именно сетевые сокеты TCP? Если они обе работают локально можно рассмотреть способ взаимодейcтвия через именованные каналы или разделяемую память (незнаю правда, как в этом случае обстоят дела с привелегиями). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 11:15:19 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaR, в коде используется следующий участок: Код: pascal 1. 2. 3. 4. 5. вопрос - у TTCPThread свойство FreeOnTerminate в какое значение установлено? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 11:17:56 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
asutp2A-MaR, утечки дескрипторов случайно нет? По крайней мере в диспетчере задач дублирующих процессов нет, FASTMM4 не ругается (пробовал также запускать службы как обычное приложение). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 11:24:54 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
wadmanA-MaR TComPort ReadFile ERROR: 0x000003E3, Операция ввода/вывода была прервана из-за завершения потока команд или по запросу приложения. Это проблема потока, где-то ошибка в нем. Оберни всё в try except и добавь логирование Exception. Добавил по максимуму, на тестовом компе ошибок нет, но попробую завтра еще раз у клиента запустить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 11:25:51 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
fortressЕсли я правильно понял, то каждый раз при отправке строки (при NeedConfirm=True) будет заново устанавливаться соединение со службой. Если сокет уже подключен к серверу, зачем нужно его закрывать и подключаться снова? Пробовал так. Если предыдущая отправка выполнялась с NeedConfirm=False, а текущая с True, то по непонятным причинам возвращается ответ предыдущей отправки. Как это лечить, пока не разобрался. fortressЕсли попробовать во время проблем с фискальником проверить в системе количество открытых сетевых соединений?Спасибо, попробую. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 11:32:11 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaRasutp2A-MaR, утечки дескрипторов случайно нет? По крайней мере в диспетчере задач дублирующих процессов нет, FASTMM4 не ругается (пробовал также запускать службы как обычное приложение). нет, речь не о процессах, а именно о дескрипторах ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 11:47:48 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
asutp2нет, речь не о процессах, а именно о дескрипторах Понял, о чем речь. Блин, действительно в одной из служб все дескрипторы TTCPThread аккуратно прибивались при остановке службы, но в процессе работы копились и копились. Возможно в этом и причина. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.07.2017, 16:18:05 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
Странно: в типе THookSocketReason предусмотрен код HR_SocketClose с комментарием {:Socket closed by CloseSocket method.}, но даже если включить его в обработку статусов в TListenerThread.ServerStatus, сервер все равно не замечает, когда клиент выполняет у себя CloseSocket (возможно по этой причине автор и не включил его в первоначальный пример). Как в этом случае отлавливать отключение клиента, чтобы вовремя прибивать его дескриптор на сервере? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 04:27:50 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
В общем, опытным путем выяснил, что этот статус HR_SocketClose срабатывает при закрытии потока на сервере, а не на клиенте. Так что видимо единственный выход - перед выполнением CloseSocket на клиенте отправлять серверу специальную команду без запроса подтверждения, и уже по этой команде сервер будет прибивать поток. Как-то примерно так (может есть более оптимальное решение?): Код: 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. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 07:24:57 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaR, добавь поддержку таймаута при обмене с клиентами. Допустим не было за последние N секунд поступлений данных от клиента - тогда принудительно рвем с ним соединение ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 08:31:19 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
A-MaRи уже по этой команде сервер будет прибивать поток. Как-то примерно так (может есть более оптимальное решение?): Это нормальное решение. Плюсом можно пинговать и если пинга не было 1-5 минут, то такое соединение считать мертвым. П.С. Хотя, в ics закрытие соединения клиентом улавливается серверной стороной. Вот как они это делают? :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 08:59:42 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
wadmanП.С. Хотя, в ics закрытие соединения клиентом улавливается серверной стороной. Вот как они это делают? :-) Возможно так. Но вообще, при попытке чтения из закрытого сокета должна возникать ошибка, возможно она и возникает, поэтому имеет смысл сделать что-то вроде: автор Код: pascal 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 11:22:59 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
alekcvp, Причёт именно WSAGetLastError, потому что в Synapse в функции WaitingData почему-то не вызывается CheckError(); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 11:24:09 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
Хотя нет, поторопился :( Вот как WaitingData реализована в BlockSock.pas: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. Если её выполнить на закрытом сокете, то, возможно, возникнет ошибка, но вы о ней не узнаете, т.к. функция тупо вернёт 0. Поэтому, возможно, вместо неё стоит вызвать напрямую IoctlSocket(FSocket, FIONREAD, Value) и анализировать её код возврата и потом уже значение Value. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 11:28:54 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
wadmanП.С. Хотя, в ics закрытие соединения клиентом улавливается серверной стороной. Вот как они это делают? :-)Ну понятно, что (скорее всего) на сервере recv висит и ждет либо данных, либо SOCKET_ERROR. Я, во всяком случае, именно так и делаю обычно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 11:41:38 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
Всем спасибо! В боевом режиме буду тестировать уже в понедельник;) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 13:05:08 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
asutp2A-MaR, в коде используется следующий участок: Код: pascal 1. 2. 3. 4. 5. Выделенное - лишнее, Terminate и WaitFor вызывает деструктор ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 13:12:54 |
|
||
|
TCP-сокеты. Покритикуйте пожалуйста код
|
|||
|---|---|---|---|
|
#18+
Квейдasutp2A-MaR, в коде используется следующий участок: Код: pascal 1. 2. 3. 4. 5. Выделенное - лишнее, Terminate и WaitFor вызывает деструктор Да, вообще можно Код: pascal 1. вместо этих 4-х строк и доп. переменной ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.07.2017, 13:19:35 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39495850&tid=2041977]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
178ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 199ms |
| total: | 460ms |

| 0 / 0 |
