Форум программистов, компьютерный форум, киберфорум
Наши страницы

Delphi и сети

Войти
Регистрация
Восстановить пароль
 
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
#1

Если я послал на сервер сокета СендБаффом (SendBuf) 10 Mb, то что мне выдаст событие ClientRead на сервере? - Delphi

06.09.2014, 20:15. Просмотров 455. Ответов 14
Метки нет (Все метки)

Собственно вопрос в следующем:
Я с клиента посылаю содержимое переменной (ну, к примеру, файл) объемом 10 Mb.
На сервере срабатывает ClientRead.
Мне в первом же срабатывании выдаст все 10 Mb, или они могут придти за 2 или больше срабатываний ClientRead?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.09.2014, 20:15
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Если я послал на сервер сокета СендБаффом (SendBuf) 10 Mb, то что мне выдаст событие ClientRead на сервере? (Delphi):

Написать соединение: много клиентов - сервер (Winsock; на сервере 3 сокета: 2 TCP и 1 UDP) - C++
Всем здрасьте !!!! Мне надо написать соединение: много клиентов - сервер Тут мне надо иметь на сервере 3 сокета: 2 TCP и 1 UDP ...

Есть ли такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят? - Видеокарты
подскажите есть такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят

Клиент Сервер SendBuf и Integer - Delphi
Доброго времени суток, облазил форум, поиск делал но так и не нашел как передать по SendBuf простоое число типа integer и возможно ли такое...

.NET 4.x Правда ли, что для приёма данных с сервера и отправки их на сервер нужно использовать два сокета - C#
Всем доброго времени суток. Пишу сетевое приложение и у меня появилось два вопроса: 1)Правда, что для приёма данных с сервера и отправки...

Программа, которая выдаст мне все пятизначные числа, начинающиеся на 9 - Turbo Pascal
Задача в общем то простая, но я не шарю в програмировании. Нужна программа которая выдаст мне все пятизначные числа, начинающиеся на 9....

Определить что послал клиент - C++
С++ и Winsock.Я пытаюсь отправить данные на сервер но сервер как-то должен определить что нам послал клиент.ПОМОГИТЕ!2 день уже пытаюсь...

Написать соединение: много клиентов - сервер (Winsock; на сервере 3 сокета: 2 TCP и 1 UDP) - C++
Всем здрасьте !!!! Мне надо написать соединение: много клиентов - сервер Тут мне надо иметь на сервере 3 сокета: 2 TCP и 1 UDP ...

Есть ли такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят? - Видеокарты
подскажите есть такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят

Клиент Сервер SendBuf и Integer - Delphi
Доброго времени суток, облазил форум, поиск делал но так и не нашел как передать по SendBuf простоое число типа integer и возможно ли такое...

.NET 4.x Правда ли, что для приёма данных с сервера и отправки их на сервер нужно использовать два сокета - C#
Всем доброго времени суток. Пишу сетевое приложение и у меня появилось два вопроса: 1)Правда, что для приёма данных с сервера и отправки...

Программа, которая выдаст мне все пятизначные числа, начинающиеся на 9 - Turbo Pascal
Задача в общем то простая, но я не шарю в програмировании. Нужна программа которая выдаст мне все пятизначные числа, начинающиеся на 9....

Определить что послал клиент - C++
С++ и Winsock.Я пытаюсь отправить данные на сервер но сервер как-то должен определить что нам послал клиент.ПОМОГИТЕ!2 день уже пытаюсь...

Написать соединение: много клиентов - сервер (Winsock; на сервере 3 сокета: 2 TCP и 1 UDP) - C++
Всем здрасьте !!!! Мне надо написать соединение: много клиентов - сервер Тут мне надо иметь на сервере 3 сокета: 2 TCP и 1 UDP ...

Есть ли такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят? - Видеокарты
подскажите есть такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят

Клиент Сервер SendBuf и Integer - Delphi
Доброго времени суток, облазил форум, поиск делал но так и

Написать соединение: много клиентов - сервер (Winsock; на сервере 3 сокета: 2 TCP и 1 UDP) - C++
Всем здрасьте !!!! Мне надо написать соединение: много клиентов - сервер Тут мне надо иметь на сервере 3 сокета: 2 TCP и 1 UDP ...

Есть ли такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят? - Видеокарты
подскажите есть такой сайт на котором я могу вбить модель материнки или процессора и мне выдаст типы видеокарт которые мне подходят

Клиент Сервер SendBuf и Integer - Delphi
Доброго времени суток, облазил форум, поиск делал но так и не нашел как передать по SendBuf простоое число типа integer и возможно ли такое...

.NET 4.x Правда ли, что для приёма данных с сервера и отправки их на сервер нужно использовать два сокета - C#
Всем доброго времени суток. Пишу сетевое приложение и у меня появилось два вопроса: 1)Правда, что для приёма данных с сервера и отправки...

Программа, которая выдаст мне все пятизначные числа, начинающиеся на 9 - Turbo Pascal
Задача в общем то простая, но я не шарю в програмировании. Нужна программа которая выдаст мне все пятизначные числа, начинающиеся на 9....

Определить что послал клиент - C++
С++ и Winsock.Я пытаюсь отправить данные на сервер но сервер как-то должен определить что нам послал клиент.ПОМОГИТЕ!2 день уже пытаюсь...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
FIL
Модератор
3409 / 2547 / 491
Регистрация: 19.09.2012
Сообщений: 7,907
06.09.2014, 20:29 #2
Цитата Сообщение от klaxwork Посмотреть сообщение
или они могут придти за 2 или больше срабатываний ClientRead
Они могут придти за любое кол-во срабатываний ClientRead.
Минимальный размер посылки 1 байт.
0
quwy
Native x86
3333 / 2180 / 597
Регистрация: 13.02.2013
Сообщений: 7,239
07.09.2014, 03:06 #3
klaxwork, О правильном использовании TServerSocket/TClientSocked и подобными компонентами
0
northener
пофигист широкого профиля
3245 / 2297 / 497
Регистрация: 15.07.2013
Сообщений: 13,549
07.09.2014, 03:14 #4
Цитата Сообщение от klaxwork Посмотреть сообщение
Мне в первом же срабатывании выдаст все 10 Mb, или они могут придти за 2 или больше срабатываний ClientRead?
Никогда, ни при каких условиях/настройках они не "придут за одно срабатывание ClientRead"!
0
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
07.09.2014, 11:41  [ТС] #5
Тогда...
Посоветуйте, как мне сделать лучше?
При срабатывании ClientRead добавлять в строковую переменную, а в отдельном потоке обрабатывать то, что есть в этой строке (насколько я знаю, размер строковой переменной может быть хоть 1 байт, хоть 2 гига)?
Или как-то еще?

Дело в том, что у меня небольшой проект почтовой программы локального масштаба (типа Outlook с Exchange сервером) и надо передавать на сервер и с сервера сообщения с прикрепленными файлами.
Потому и интересуюсь.

Спасибо.

Добавлено через 19 минут
А точнее меня интересует вопрос такой:
К примеру я с клиента на сервер посылаю сообщение размером те же 10 мегабайт одним разом через SendBuf.
На сервер пришло 5 мегабайт первой партией.
И если я с этого же клиента пошлю сразу же за первым сообщением посылаю еще 10 мегабайт, то они могут придти на сервер раньше, чем придет вторая партия от первого сообщения? Или пока сервер не примет полностью первое сообщение, он не примет второе?

Добавлено через 7 минут
Ну или упрощу. Первое сообщение: "текст первого сообщения".
Второе сообщение: "1234567890".
Второе сообщение посылаю сразу за первым. Посылаю с помощью SendBuf.
Может ли случиться такая ситуация, что на сервер придут данные вида "текст пер1234567890вого сообщения"?
0
cotseec
Пишу на Delphi...иногда
1402 / 1262 / 174
Регистрация: 03.12.2012
Сообщений: 3,914
Записей в блоге: 5
Завершенные тесты: 3
07.09.2014, 13:42 #6
разработайте протокол общения, например: в первых байтах сообщения посылайте длину передаваемых данных, на приеме соответственно накапливайте весь пакет, согласно пришедшего заголовка, и рапортуйте о приеме пакета с номером, на отправляющей стороне следующий пакет отправляйте только после получения рапорта о доставке
и сразу все 10 Мб не посылайте - разбейте на куски, например, по 200 байт
0
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
07.09.2014, 13:58  [ТС] #7
И я не прошу готового кода. Я прошу идею, как организовать передачу и прием данных, если пользователь будет работать с программой.
У меня есть несколько идей, но хотелось бы узнать, какие есть еще принципы передачи данных в таких системах.

Вот одна из моих идей по организации передачи данных.
Когда я пытался передавать файл 10 Mb по частям по 10 килобайт на серверную часть, которая была запущена на том же компе, где и клиент, то происходили потери данных.
Так же пробовал передавать на другой комп.
Пробовал передавать и сплошным потоком, и с паузой в виде Sleep(50) между кусками...
Но из 10 мегабайт приходило то 7 Mb, то 9 Mb...

Передавал сообщения такой структуры:
первые 8 байт -- длина сообщения. Она составляется в конце формирования сообщения.
Далее:
Id пользователя+#0+тема сообщения+#0+само сообщение+#0+id кому адресовано+#0+ etc...
Файл примерно так же:
Id пользователя+#0+реальное имя файла+#0+номер файла в сообщении (их может быть несколько в одном сообщении и с одним именем из разных папок)+#0+длина файла+#0+длина куска+#0+позиция куска+#0+дата посыла файла(уникальна для каждого файла с микросекундами вида "20140907123456123" где идет дата и время 12:34:56:123 07.09.2014 г.)+#0.

Прием был организован таким образом:
При срабатывании ClientRead смотрится, сколько байт в буфере. Если меньше 8 байт, то ждать следующего срабатывания. Эти 8 байт являются длиной сообщения вида 00000025 (т.е. длина сообщения 25 байт вместе с этими 8 байтами).
Далее, если больше 8 байт, то взять эти 8 байт и взять все сообщение из буфера. Если оно не полное, то в бесконечном цикле ждать прихода всего объема сообщения (в цикле есть Application.ProcessMessages).
Как только пришел полный объем сообщения -- начинаю его обрабатывать.

Так же пробовал ВСЁ, что приходит при ClientRead, записывать в массив Record:
Delphi
1
2
3
4
5
6
7
  RConns = Record //сокращение от Connections
    H: HWND; //идентификатор сокета Socket.Handle, который вызывается в ClientRead
    S: string; //строка со всеми данными, приходящими в событии ClientRead сплошной строкой
    B: Boolean; //флаг занятости этой строки (Busy)
                    //если True, то в строку что-то добавляется или что-то удаляется из нее.
                    //это чтоб не одновременно работать с ней.
  end;
А отдельный поток Thread уже смотрит, какой длины эта строка. И далее, если больше 8 байт, то обрабатывать.
В общем так, как было описано ранее.

Прошу прощения за такую писанину, но не знаю как еще описать.
0
FIL
Модератор
3409 / 2547 / 491
Регистрация: 19.09.2012
Сообщений: 7,907
07.09.2014, 15:28 #8
Откуда там цикл взялся, если данные принимаются по событию ClientRead?
0
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
07.09.2014, 15:41  [ТС] #9
FIL, цикл запускается для того, чтоб принять полностью все данные текущего сообщения.
Т.е. если пришли только 10 байт из 100 байт всего сообщения (первые 8 байт -- размер всего сообщения, +2 байта от самого сообщения), то запускаю бесконечный цикл, который ждет, пока Socket.ReceiveLen не станет >0.
Как только появились данные -- опять читаю. Значит это пришла следующая часть этого сообщения. И так пока не придут все 100 байт сообщения.
Как только пришли все 100 байт -- цикл прерывается и я начинаю обрабатывать сообщение. (если это кусок файла, то пишу в файл; если это запрос списка пользователей, то отправляю клиенту список; etc...)

Потому что если пришли только 20 первых байт при одном срабатывании события, то в следующем срабатывании будет 2-я часть сообщения, но она уже не будет содержать длины сообщения, или куска файла.
Т.е. я передаю строку "00000031001:002:текст первого сообщения".
На сервер приходят первые 20 байт.
Они содержат строку "00000031001:002:текс".
Здесь первые 8 байт ("00000031") это длина всего сообщения, чтоб я знал, сколько мне надо читать из буфера, чтоб прочитать сообщение полностью.
Далее тут идет 001 -- id пользователя отправителя, 002 -- id пользователя получателя, далее идет текст.

Если в этом событии сообщение не пришло полностью, то при следующем срабатывании события у меня в строке будет "т первого сообщения". И тут уже неизвестно, сколько должна быть длина этого сообщения.
Соответственно надо либо ждать принудительно, пока не придет все сообщение целиком, либо куда-то складывать все части, и опять же все время смотреть на этом "складе", пришло ли сообщение целиком.
0
FIL
Модератор
3409 / 2547 / 491
Регистрация: 19.09.2012
Сообщений: 7,907
07.09.2014, 15:50 #10
Цитата Сообщение от klaxwork Посмотреть сообщение
цикл запускается для того, чтоб принять полностью все данные текущего сообщения.

При сработке ClientRead данные вычитываются и, если надо, обрабатываются и/или сохраняются (накапливаются) до прихода след. пакета, - никаких циклов.
0
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
07.09.2014, 16:29  [ТС] #11
FIL, да. А сохранять надо в какой-то глобальной переменной т.к. если она будет локальной, то данные будут теряться.

Но что мне тогда использовать в качестве глобальной переменной? Массив из строковых переменных, или что-то другое? Или массив из TStringList-ов например?

Добавлено через 1 минуту
Где в каждом элементе будет по одному сообщению? Но тогда опять же надо сообщение как-то собирать целиком.
А чтоб не работать одновременно нескольким процессам с переменной, нужен флаг, определяющий, работает с этой переменной кто-либо или нет.
Так?
0
FIL
Модератор
3409 / 2547 / 491
Регистрация: 19.09.2012
Сообщений: 7,907
07.09.2014, 16:40 #12
Цитата Сообщение от klaxwork Посмотреть сообщение
что мне тогда использовать в качестве глобальной переменной?
Зависит от передаваемых данных. Если текст, то можно в строку все это складывать; если бинарные данные, то массив или Stream.
Цитата Сообщение от klaxwork Посмотреть сообщение
А чтоб не работать одновременно нескольким процессам с переменной
У каждого процесса должна быть своя переменная.
0
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
07.09.2014, 18:12  [ТС] #13
FIL,
Цитата Сообщение от FIL Посмотреть сообщение
Зависит от передаваемых данных. Если текст, то можно в строку все это складывать; если бинарные данные, то массив или Stream.
Но я не знаю, какие данные у меня пойдут в следующий момент. Это может быть и просто текстовое сообщение, а может быть и кусок файла.
Цитата Сообщение от FIL Посмотреть сообщение
У каждого процесса должна быть своя переменная.
Как я понимаю процесс = событие ClientRead?

Добавлено через 2 минуты
Или под процессами стоит понимать как событие ClientRead, так и просто обработку этой строки?
Т.е. в обработке события ClientRead в переменную заносятся данные, а в параллельном потоке из нее извлекаются данные, и удаляются те, которые были извлечены.
Так?
0
FIL
Модератор
3409 / 2547 / 491
Регистрация: 19.09.2012
Сообщений: 7,907
07.09.2014, 18:42 #14
Цитата Сообщение от klaxwork Посмотреть сообщение
Но я не знаю, какие данные у меня пойдут в следующий момент.
Для этого и нужно придумать
Цитата Сообщение от cotseec Посмотреть сообщение
протокол общения
Цитата Сообщение от klaxwork Посмотреть сообщение
процесс = событие ClientRead?
процесс = клиент, шлющий данные серверу.

Вообще, в сети дофига примеров программ с сокетами: чаты, файлообменники и т.п.
0
klaxwork
16 / 16 / 0
Регистрация: 28.05.2013
Сообщений: 185
07.09.2014, 21:17  [ТС] #15
Цитата Сообщение от FIL Посмотреть сообщение
Вообще, в сети дофига примеров программ с сокетами: чаты, файлообменники и т.п.
Да, но там разбираются только однопользовательские приложения или только передача текста. Но не передача сообщений и файлов в многопользовательском клиент-серверном приложении.
0
07.09.2014, 21:17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru