![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Передача файла с помощью TServerSocket и TClientSocket [D5]
Anonimus © (2003-09-19 11:27:00)
Драсти вам..!!!!
Вот какая проблема, перед передачей файла я посылаю строку заголовка, которая содержит имя файла размер и т.д. я покапался в архивах и там написано что нужно посылать так SendBuf(@Stroka[1], SizeOf(Stroka));, но так не работает выдает ошибку, тогда
посылаю я ее так: SendBuf(Stroka[1], SizeOf(Stroka)); но проблема в том что эта строка приходит через раз, т.е. бывает что не приходит и программа приемник зацикливается....
Вообщем как быть..????
Подскажите плиз..!!!
mOOx_ (2003-10-02 16:54:00) [1]
"...но почему не работает вот так: SendBuf(@Stroka[1], SizeOf(Stroka));?????..." Это уже на орех тянет после разъяснения на полтора экрана :).
Digitman (2003-09-23 15:12:00) [2]
о боже !!!!!! я ему про фому, он мне про ерему))))))
Anonimus (2003-09-23 14:40:00) [3]
>Digitman Спасибо все это я понял..!!!!
но почему не работает вот так: SendBuf(@Stroka[1], SizeOf(Stroka));?????
Stroka : String;
Digitman (2003-09-23 14:03:00) [4]
Пойми, что переменные дин.типа, к каковым относятся, например, String или array of sometype, всегда представлены компилятором в памяти приложения как указатель на что-то другое, хранящее реальные данные ! а размер указателя в Win32 всегда равен 4 байта ! Их-то ты и получаешь в рез-те обращения к SizeOf(переменная дин.типа)...
в то же время метод
function SendBuf(var Buf; Count: Integer): Integer;
ожидает 1-м параметром адрес, по которому хранятся данные для передачи, 2-м - полный размер передаваемых данных, начиная с адреса, указанного 1-м параметром
если ты пишешь
SendBuf(Stroka[1], SizeOf(Stroka)),
то 1-м параметром ты передаешь не собственно адрес переменной Stroka, а адрес 1-го символа в буфере строки, которым управляет переменная Stroka. Это вполне корректно. Но ! 2-м параметром следует указать текущий размер буфера строки, каковой определяется, например, вызовом ф-ции Length(Stroka), ты же передаешь совсем иное - размер указателя, каковым представлена переменная Stroka в памяти.
Корректно было бы сделать и так тоже
SendBuf(PChar(Stroka) ^, Length(Stroka))
Здесь конструкцией PChar(Stroka) ^ты говоришь компилятору : в кач-ве адреса буфера следует взять непоср.адрес строковых данных. Обрати внимание на оператор разыменования- ) ^! Он обязателен, когда речь идет о передаче чего-то (заранее неизвестного на этапе компиляции) фактическим параметром по ссылке, а не по значению.
префикс VAR как раз и предписывает компилятору ожидать ссылку, а не само значение
но, скажем, в случае
var
buf: Byte;
..
SendBuf(buf, SizeOf(buf));
все будет вполне корректно, ибо видя такую конструкцию, компилятор сгенерирует код, который в ран-тайм будет передавать 1-ым факт.параметром ИМЕННО АДРЕС переменной buf, а не ее значение. Т.е. буфером будет являться то, что лежит по адресу, совпадающему с адресом переменной buf. Соответственно и SizeOf(buf) вернет "единицу", ибо компилятор знает, что размер переменной buf (интерпретируемой нами как некий буфер передачи) равен размеру типа byte, т.е. "единице"
Digitman (2003-09-23 13:41:00) [5]
> когда я так делаю
как "так" ?
твой вариант
SendBuf(Stroka[1], SizeOf(Stroka)); // где Stroka: String;
не подходит ни под один из допустимых (или корректных) вариантов в посте
> Digitman © (23.09.03 12:30) [8]
адрес буфера Stroka[1] ты здесь указал (он совпадает с 1-м символом буфера строки, хранимой в структуре переменной Stroka), но почему же SizeOf() ??? разве размер строковых данных в буфере строки совпадает с размером переменной Stroka ? Это же совсем разные значения !! SizeOf(Stroka) для String-переменной Stroka всегда даст 4 байта (размер указателя на пеменную), в то время как Length(Stroka) даст тек.размер строковых данных, контролируемых внутренними структурами этой переменной, т.е. как раз то что тебе и нужно !!
SizeOf() подошел бы, например, если бы Stroka была объявлена как array[..] of чего_то_там, но уж никак не String) .. и уж тем более не дин.массив вида array of чего_то_там)
вникай ! вникай в полярную разницу объявлений тех или иных типов и реально происходящено при их использовании в данном и прочих похожих случаях ! пока в этом не разберешься досконально, дальше нет смысла двигаться - грабли будут упорно лупить тебя в одну и ту же точку))))
Anonimus (2003-09-23 12:40:00) [6]
>потому что в примерах в кач-ве 1-го параметра вызова SendBuf() я приводил непосредственно адрес буфера, а не адрес динамической структуры, хранящей внутри себя в т.ч. адрес буфера
Дк я про это и говорю что когда я так делаю он ругается...!!!
Digitman (2003-09-23 12:30:00) [7]
прочувствуй разницу
1.
var
buf: String;
...
SendBuf(PChar(buf)^, Length(buf));
или, что эквивалентно
SendBuf(buf[1], Length(buf));
2.
var
buf: Pointer; // или PChar или PByte или PByteArray или ....
...
SendBuf(buf^, размер_данных_на_которые_указывает_buf);
3.
var
buf: array[0..X] of SomeType;
...
SendBuf(buf, SizeOf(buf));
Digitman (2003-09-23 12:24:00) [8]
потому что в примерах в кач-ве 1-го параметра вызова SendBuf() я приводил непосредственно адрес буфера, а не адрес динамической структуры, хранящей внутри себя в т.ч. адрес буфера
Anonimus (2003-09-23 12:13:00) [9]
> Digitman
> в таком случае выражение SizeOf(Stroka) всегда равно 4 байта.
Да это я заметил..))))
а почему тогда во всех ваших примеров которые вы давали в форумах вы используете только SizeOf?????
Digitman (2003-09-22 13:09:00) [10]
> Anonimus
> Stroka декларированна как String
в таком случае выражение SizeOf(Stroka) всегда равно 4 байта.
прочувствуй разницу между SizeOf(Stroka) и Length(Stroka) !!
> Гнездо неблокирующие
значит событие OnClientWrite() обязательно к обработке серверной (передающей) стороной
> приемник организован на строне клиента
надо понимать, что клиент никогда ничего не передает серверу ? передача ведется исключительно в направлении "сервер --> клиент" ?
если передача ведется в какой-то момент и в обратном направлении, то событие OnWrite() так же обязательно к обработке
клиентской (передающей) стороной
Anonimus (2003-09-22 11:13:00) [11]
> Digitman
Stroka декларированна как String; Гнездо неблокирующие.. и приемник организован на строне клиента....
Verg (2003-09-19 15:17:00) [12]
> Или возми котовый компонент TCP опяттаки из Indy.
Это "не спортивно" :)
Master (2003-09-19 15:15:00) [13]
Да используй ты UDP из Indy а то опять обяснять придется буферезацию посылки. Или возми котовый компонент TCP опяттаки из Indy.
Digitman (2003-09-19 14:24:00) [14]
1. Как декларирован идентификатор Stroka ?
2. Гнездо передатчика неблокирующее ? Если да, то обрабатываешь ли событие On[Client]Write ?