Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Реализую клиет сервер на основе функций из winsock2.h Долго не мог понять в чем проблема но получается что если сразу сделать две отправки от клиента к серверу или наоборот что то типо Код: plaintext 1. 2. то сообщение как бы объединяется в одно, иногда все ок получается два отдельных сообщения, но иногда так иногда не так это конечно проблема. Как можно однозначно разделить сообщения на разные ? Есть какие то средства в winsock2 или единственный путь придумывать какой то свой разделитель? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 12:32 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
trom, Это стандартное поведение TCP сокетов. TCP это транспорт который доставляет поток байтов. Он не разделяет этот поток на сообщения. Вам надо на уровне приложения уметь различать разные сообщения. Например перед каждым сообщением записывать в сокет его длину. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 12:36 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, А можно пример на с++, как записывать и считывать ? Длинна же может быть из одной цифры, а может из трех итд Какое то стандартное решение для этого наверняка уже есть, не хотелось бы сочинять свои велосипеды в такой важной части кода как клиент сервер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 13:44 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
tromДлинна же может быть из одной цифры, а может из трех итд Раз у тебя протокол текстовый, то делай текстовый разделитель посылок. Обычно в таких случаях используется символ конца строки. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 13:57 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
tromКакое то стандартное решение для этого наверняка уже есть, не хотелось бы сочинять свои велосипеды в такой важной части кода как клиент сервер. Почитай RFC по протоколам HTTP, SMTP, POP3. Там как раз описано стандартное решение. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 13:59 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
trom, примерно так (если без обработки ошибок) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. recv_all - это написанная вами функция, которая в цикле вызывает стандартную recv пока из сокета не будет прочитано ровно len байтов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 14:04 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Стандартный recv у меня уже в цикле while ждет сообщений Код: plaintext 1. 2. 3. То есть идея как я понял такая, преобразованная в строку переменная типа int имеет стандартную длину, сначала считываться значение int, а потом преобразуется из строки обратно в int и уже считывается само сообщение ? непойму если эта часть Код: plaintext 1. преобразует int в строку, то как из строки получить значение типо int ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 15:08 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Вернее даже так как из начала строки прочитать количество символов равным int len; sizeof(len); и преобразовать полученный результат в обычное число int. и прочитать часть строки от значения sizeof(len) до числа полученного из int. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 15:12 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
tromСтандартный recv у меня уже в цикле while ждет сообщений Код: plaintext 1. 2. 3. Еще раз: recv не читает сообщения. Он читает поток байтов кусками случайной длины. Поэтому чтобы прочесть например int который является 4-мя байтами, вам нужно вызывать в цикле recv пока не будут прочитаны ровно 4 байта. Не больше не меньше. Поэтому ваш цикл с recv не годится. Как я выше сказал, напишите функцию recv_all и используйте ее для чтения фиксированного кол-ва байтов. Например так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. tromнепойму если эта часть Код: plaintext 1. преобразует int в строку, то как из строки получить значение типо int ? Тут нет преобразования в строку. Тут бинарное представление int рассматривается как массив char. Такие базовые вещи С/С++ надо бы уже знать прежде чем писать сетевые программы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 16:05 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
tromКакое то стандартное решение для этого наверняка уже есть, не хотелось бы сочинять свои велосипеды в такой важной части кода как клиент сервер. Почитай про ZMQ . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 19:21 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
топикстартеру: еще раз, есть два протокола основных передачи данных в TCP/IP: UDP и TCP. UDP пакетный, там есть пакеты и ты посылаешь и получаешь пакеты, но правда порядке пакетов не гарантирован и доставка тоже не обязательна. TCP - наоборот, потоковый. пакетов нет, но доставка гарантирована. потоковый - это как любой файл или поток ввода/вывода: читаешь байтик за байтиком, и все. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.12.2013, 20:48 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
trom...Долго не мог понять в чем проблема но получается что если сразу сделать две отправки от клиента к серверу или наоборот....или единственный путь придумывать какой то свой разделитель? Офф/2: Поздравляю! Вы один из не многих, кто увидел грабли в листве. Многие присыпают листвой потолще, у кого-то широкий шаг(в смысле тестирования не увидели)... Тут всё верное прозвучало выше. TCP - потоковый. Ответ на Ваш вопрос становится очевиден, если представить как течёт поток воды и Вам надо отделять одну молекулу от другой. Но в сокетах немного попросче - Вы можете задавать строгую последовательность нескольких молекул(не встречающихся в основном потоке) - т.е. некий префикс вашему кванту. Либо заранее знать сколько Вы хотите получить на приёме. Для этого, обычно всегда передают заголовок(а на приёмной стороне он всегда гарантировано будет принят и он не делим) и из него знают длину хвоста идущего за ним. Ну или как тут уже прозвучало - поменять протокол. Но Это всё-же похоже не для Вашей задачи... удачи Вам (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 03:52 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Пример не рабочий. Сижу разбираюсь целый день, тут какая то сложная работа с указателями пока я даже логику понять не могу. А можно написать пример который будет работать ? то есть есть две отправки первая это длинна сообщения, вторая это само сообщение и получатель должен получив сначала длину корректно прочитать основное сообщение К примеру функция recv_all(SOCKET s, char* buf, int len) зависает при выполнении первый send вроде выводит но получает что то непонятное вроде знаков ====, а второй до конца обработать не может Что и как править я разобраться не могу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 14:29 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
trom, Придумывать и отлаживать код за вас лень. Давайте вы приведете ваш код, а мы скажем что поправить. А то иди знай что у вас не работает, может вы неправильные аргументы передаете. Телепаты в отпуске. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 16:03 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Ок тогда просто скину весь код клиент сервера с кодом из вашего примера Как понимаю нужно править только клиент и его способ получения данных в нем вся проблема, а если отладить получение на клиенте то просто вставить ту же функцию на сервер и все. Клиент Код: plaintext 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. Сервер Код: plaintext 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. } ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 16:52 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. Выводят мусор еще до попытки получения данных пакета. Какой смысл выводить что там в свежевыделенной памяти валяется? Особенно когда buff2 нигде не используется и не освобождается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 17:09 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
wst, делать то что? удалить их? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 17:17 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Вот это Код: plaintext 1. заменить на Код: plaintext 1. Кроме того, как выше сказали, это бессмысленный кусок кода, выводящий мусор. Код: plaintext 1. 2. Кроме того, если вы передаете длину сообщения, то это нужно делать везде, а не по желанию, в том числе и в серверной части. Кроме того, после комментария Код: plaintext 1. у вас только код принимающий данные, т.е. комментарий противоречит коду. Но это ладно. А вот, хоть сервер и пытается читать с клиента, но клиент ни разу ничего не отправляет. Как поправите эти очевидные баги, приводите очередной вариант кода, будем смотреть дальше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.12.2013, 21:23 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Выше правильно уже прозвучали необходимые доработки... свои 5 копеек... trom ... Сервер Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. данная увязка потоков быдет плыть при ударных нагрузках на сервак. И в случаи аварийных остановов или быстрое внешняя попытка отгрузки программы в некоторых случаях будет приводить к очень интересным поведениям. Или по другому... Т.к. при вызове бегинсреад потоку ещё управление не передалось, и в случае короткого времени жизни приложения вообще не передастся, и Вам пофигу: начала работу ниточка или нет - предлагаю вообще нитку не запускать (в некоторых случая так оно и будет). и ышо... то что у вас и приветная и ответная части обе слушают - то ничего не будет(это уже прозвучало выше). Обратите внимание как слушает клиент. Что он ожидает (длину данных и тип), и что делает после этого. Ответная часть(в частности сервак) должен именно так(и такие размерности) и послать данные... удачи вам (круглый) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 02:42 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Код заменил теперь вроде ничего не зависает и передается, но я не могу понять как извлечь из Код: plaintext 1. значение длинны последующего сообщения ведь тут в функцию не передается массив char, тут у нас (char*)&len Код: plaintext 1. 2. А этот код работает но значение длинны сообщения 5 я поставил сам ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 08:40 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
kolobok0, Не понял предлагаете не использовать _beginthreadex( и сделать просто последовательный сервер ? или я его как то не так использую ? В примере клиент сервера на котором я основывался была функция CreateThread про которую писали что лучше ее заменить на _beginthreadex (так как у меня просто консольное приложение), я и заменил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 08:43 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
trom Код: plaintext 1. Тут вы читаете из сокета int в переменную len и тут же затираете его, присваивая возвращаемое значение recv_all (сколько байтов прочитано) в ту же переменную len. Используйте разные переменные для этих двух длин. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 09:01 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
tromтут в функцию не передается массив char Несмотря на то, что параметр функции объявлен как char*, функция работает с любым указателем, поскольку ей не нужно интерпретировать массив байт. Если хотите, можете полезть в заголовочные файлы и заменить тип этого параметра на void*. Может, тогда в Вашем мозгу что-нибудь прояснится. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 14:17 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
Anatoly Moskovsky, Все наконец заработало спасибо! только я непойму а как сделать цикл типа while который ждал бы сообщений в бесконечном цикле то есть нужно что то типо Код: plaintext 1. 2. Но с использованием вашей функции recv_all ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 14:31 |
|
||
|
Как разделить сообщения на клиент сервере
|
|||
|---|---|---|---|
|
#18+
trom, nclients--; // уменьшаем счетчик активных клиентов У тебя доступ к этой переменной из разных потоков без синхронизации. Будут гонки ( rase conditions ). Тебе надо защищать доступ к этой переменной мьютексом или критической секцией. Конкретно здесь лучше всего заменить изменение переменной на InterlockedIncrement/Decriment msdn.microsoft.com/en-us/library/windows/desktop/ms683614(v=vs.85).aspx ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.12.2013, 15:28 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38509975&tid=2019787]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
61ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
| others: | 11ms |
| total: | 169ms |

| 0 / 0 |
