2 / 2 / 0
Регистрация: 08.05.2013
Сообщений: 14
|
||||||
1 | ||||||
(WinSock) Условие прихода пакета данных20.07.2013, 00:07. Показов 3217. Ответов 6
Метки нет (Все метки)
Допустим, я хочу написать чат на WinSock. Мне нужно, чтобы при приходе пакета специально отведенный буфер заполнялся данными, после чего выводился на экран в виде текста.
Как определить, пришел ли пакет с данными? Есть ли специальное условие? На подобии " if( если пришел пакет с сервера ) { код } Сработает-ли такое условие?
Если не правильно понял механику того, как это работает, напишите.
0
|
20.07.2013, 00:07 | |
Ответы с готовыми решениями:
6
Порядок прихода данных Вывод даты прихода товаров из данных регистра бухгалтерии. Прием данных Winsock и преобразование данных Byte в String Прием данных в WinSock |
Ушел с форума
|
|
20.07.2013, 00:38 | 2 |
Верно. Только с одним "но".
TCP - это просто поток байт, в нем нет такого понятия, как пакет или сообщение. Если на одном конце кто-то вызвал send с "привет, колян!", то на другом конце recv вовсе не обязана прочесть эту строку за один вызов, может получиться, например, такая последовательность: "прив", "ет, кол", "ян!". Работать с TCP следует исключительно как с потоком байт, разбитым на фрагменты заранее неизвестного размера - только так и никак иначе. Конец "сообщения", если таковое имеет какой-то смысл в приложении, определяется не количеством байт, прочитанных за один вызов recv, а по содержимому этих байт (например, по какому-нибудь маркеру или спец. символу). Ну и не забывайте, что recv может вернуть код ошибки (-1) или 0. Последнее означает, что удаленный компьютер разомкнул свой конец соединения.
2
|
2 / 2 / 0
Регистрация: 08.05.2013
Сообщений: 14
|
|||||||||||
20.07.2013, 01:08 [ТС] | 3 | ||||||||||
То есть, в моем случае (бесконечный цикл приема данных) я скорее всего приму не "[Андрей] Привет, колян!", а "[А", "н", "др", "е" и т.д. ? Или сообщение считается до конца ( или в TCP нет такого понятия, как конец или начало сообщения? ), прежде чем будет выведено на экран? Если я понял верно, мне нужно использовать UDP ( recvfrom(), sendto() ) способ подключения для моей задачи?
Добавлено через 8 минут Если Вам не составит труда, прочитайте внимательно код в основном посте. Если мои догадки верны, то я скорее получу в текстбоксе такую надпись (Если придет сообщение: "[Андрей] Привет, колян! [qweqwe] [123]") :
0
|
377 / 228 / 79
Регистрация: 24.11.2009
Сообщений: 695
|
|
20.07.2013, 01:46 | 4 |
0
|
Ушел с форума
|
|
20.07.2013, 10:15 | 5 |
Именно. Нет такого понятия.
TCP - это просто поток байт. recv принимает этот поток частями заранее неизвестного размера. Переходить на UDP необязательно, данная задача может быть решена и на TCP, просто нужно использовать какой-то маркер для того, чтобы обозначать конец сообщения. И recv вычитывать данные до тех пор, пока не встретится этот маркер (или ошибка).
1
|
2 / 2 / 0
Регистрация: 08.05.2013
Сообщений: 14
|
|
20.07.2013, 12:12 [ТС] | 6 |
Т.е. нужно использовать GetToken? "[Андрей] Привет, колян!%", и считывать вплоть до символа '%' ? Как реализовать такой код? Я не совсем понимаю.
0
|
Ушел с форума
|
|
20.07.2013, 13:49 | 7 |
Прежде всего, нужна система определения границ сообщений, передающихся по TCP.
Сам TCP, как Вы уже поняли, таких границ не предоставляет. Поэтому нужен протокол поверх TCP, в котором эти границы были бы определены. Например, можно каждое сообщение предварять определенным количеством байт, в которых указывать его длину. Тогда recv сначала будет вычитывать из сокета эти байты, а затем, получив длину, вычитывать остаток сообщения, зная сколько именно байт должно прийти. Другой распостраненный подход - определять конец сообщения по его содержимому. Например, в HTTP большинство сообщений имеют заголовок, в котором указывается длина, а затем тело указанной длины. Для Вашего случая подойдет какой-нибудь специальный символ-разделитель, который не встречается в тексте - как на счет \0 ? То есть: "Привет, Андрей !0Как дела ?0Где вчера пропадал ?0". Итак, протокол сформирован, теперь нужен парсер протокола - компонент, которому вы сможете "скармливать" данные, порезанные сетью на фрагменты, и который будет "склеивать" из них целые сообщения. Например, отправляем в парсер "При", "вет, А", "ндрей!0Как д", "ела", "?0" - он возвращает нам строку "Привет, Андрей" (без нуля, разумеется), затем "Как дела ?" и т.д. Ну а дальше все просто - читаете в цикле данные из recv и кидаете их в парсер. Он возвращает готовые целые сообщения, которые можно отображать в окне чата.
2
|
20.07.2013, 13:49 | |
20.07.2013, 13:49 | |
Помогаю со студенческими работами здесь
7
Winsock - сливание данных И снова WinSock. UDP. Прием данных. Delphi winsock отправка больших данных Знаки ? при отправки данных в winsock Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |