Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.03.14;
Скачать: CL | DM;

Вниз

Пересылка данных типа TStringList через сокеты   Найти похожие ветки 

 
samalex   (2004-01-08 13:46) [0]

Уважаемые знатоки!!!
Я пытаюсь передавать массив данных с помощью переменной TStringList. С главного компьютера (ServerSocket) данные рассылаются на другие ПК (ClientSocket).

ServerSocket : по таймеру
For i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
begin
ServerSocket1.Socket.Connections[i].SendBuf(PrStringList, Length(PrStringList.text));
end;

ClientSocket : событие OnRead
PrStringList:=TStringList.Create();
TCustomWinSocket(Sender).ReceiveBuf(PrStringList, TCustomWinSocket(Sender).ReceiveLength);
Memo1.Lines:=PrStringList;
PrStringList.Destroy;

На клиенте при приеме данных возникает ошибка. Может быть, вообще невозможно передавать данные пр помощи StringList? Я использовал просто длинную строку, но на некоторых ПК на "обрезалась" - данные приходили неполностью.


 
Fredericco ©   (2004-01-08 14:13) [1]

ClientSocket : событие OnRead
Memo1.Lines.Add(Socket.ReceiveText);


 
Карелин Артем ©   (2004-01-08 14:15) [2]

PrStringList - Обьект?
Length(PrStringList.text) - Длина текста?

Это называется "Копать от меня до обеда".


 
axx ©   (2004-01-08 14:20) [3]

st:TStreame;
PrStringList.SaveToStreame(st);
Socket.SendStream(st);
:)


 
Fredericco ©   (2004-01-08 14:21) [4]

ServerSocket : по таймеру
For i := 0 to ServerSocket1.Socket.ActiveConnections-1 do
begin
ServerSocket1.Socket.Connections[i].SendText(PrStringList.Text);
end;


 
samalex   (2004-01-08 15:01) [5]

Карелин Артем
Нужно Length(PrStringList)?

А на приемной стороне?


 
Fredericco ©   (2004-01-08 15:09) [6]

[1]Приемная
[4]Отправляющая


 
samalex   (2004-01-08 15:15) [7]

Fredericco
Извини, я написал, что не хочу отправлять данные при помощи
SendText(PrStringList.Text).
"на некоторых ПК на "обрезалась" - данные приходили неполностью".
Я хотел попробовать другой тип передачи данных...


 
samalex   (2004-01-08 15:23) [8]

axx ©
Ладно, это мы передали данные ...
А прием как организовывать?


 
Fredericco ©   (2004-01-08 15:25) [9]

Без разницы. ТСП потоковый протокол, короче любые передаваемые тобой данные могут склеиваться или разбиваться на части и приходить по частям. Способ отправки тут не причем. Есть два выхода из этой ситуации:
1) Самому организовать грамотную прием/отправку.
2) Воспользоваться сторонними компонентами, например, Indy.


 
Fredericco ©   (2004-01-08 15:30) [10]

samalex (08.01.04 15:23) [8]
Как думаешь что там конкретно передалось?
1) В методе SendBuf два параметра: указатель на данные и их длина.
Указатель - это число: адрес в памяти. Все это имеет смысл если данные идут последовательно с указателя по длину.
2) Чем по-твоему принципиально отличается SendText(PrStringList.Text) и SendBuf(PrStringList,....)?

ЗЫ. И давай на "ты".


 
Verg ©   (2004-01-08 15:35) [11]


> SendText(PrStringList.Text).
> "на некоторых ПК на "обрезалась" - данные приходили неполностью".


А почему они "приходили" неполностью вопроса не возникало?

Опять та же песня про ПОТОЧНОСТЬ TCP/IP.

Этот протокол, при наличии соединения ГАРАНТИРУЕТ, что данные отправленные одной стороной придут в той же последовательности и в том же составе на принимающую сторону. А вот время доставки и "сгруппированность" этих данных он (протокол) НЕ ГАРАНТИРУЕТ.
Грубо говоря, если сделать две отправки
send("A");
send("BC");
то на принимающей строне возможно принять
1. recv -> "A", recv -> "B", recv -> "C"
2. recv -> "AB", recv -> "C"
3. recv -> "ABC"
4. recv -> "A", recv -> "BC"

Для передачи блочных по смыслу данных через потоковый канал надо в самих данных предусматривать "маркеры", означающие конец логического блока данных.
Такими маркерами могут быть, например, спец-символы (для передачи текстовых данных), ну например символ #0 и т.п.
Т.О.

SendText(StrList.Text+#0);

Принимающая сторона должна просто продолжать принимать порции данных и объединять их последовательно до тех пор, пока в принятых данных не встретится такой "маркер", либо произойдет разрыв TCP соединения.


> Я хотел попробовать другой тип передачи данных...


Это не тип передачи, это просто "другой фантик" для все тех же фу-ций recv(from) и send(to).


 
samalex   (2004-01-08 15:35) [12]

Fredericco ©
Общая длина строки у меня получается где-то 3.5 кб и, как я уже писал, при использовании метода SendText(PrStringList.Text) и
Socket.ReceiveText время-от-времени начало стороки "обрезается".
Что значит "1) Самому организовать грамотную прием/отправку."?


 
Fredericco ©   (2004-01-08 15:52) [13]

Более, менее правильная отправка.

function TSendToSocketTh.SendTextToServEx(Text:String):boolean;
var
p:PChar;
LReal,LNeed:integer;
tmp:string;
begin
Result:=False;
if (not csDrv.Active) or (InConnecting) then begin
Result:=True;
Exit;
end;
tmp:=Text;

LReal:=csDrv.Socket.SendBuf(Pointer(tmp)^,Length(tmp));
if LReal>-1 then begin
Delete(tmp,1,LReal);
LNeed:=Length(tmp);
while LNeed>0 do begin
LReal:=csDrv.Socket.SendBuf(Pointer(tmp)^,Length(tmp));
Delete(tmp,1,LReal);
LNeed:=Length(tmp);
end;
Result:=True;
end Else begin
WaitingOnWrite:=True;//Сокет занят, см. пояснение ниже
SendToSocketTh.Suspend;
end;
end;

Сокет, может быть занят, о чем о скажет вернув -1 в методе send.
Необходимо обрабатывать такое событие как OnWrite, которое символизирует о готовности сокета к отправке данных.
Иными словами, отправляешь ты 3.5 Кб данных, отправил 0.5 сокет говорит - погоди. Ждешь событие OnWrite и отправляешь оставшиеся 3.0 Кб таким же макаром. Причем, все это справедливо как для клиента, так и для сервера.
Кстати, правильней начинать работу с сокетом не после OnConnect, а после первого OnWrite.

А про прием см. Verg © (08.01.04 15:35) [11] .



Страницы: 1 вся ветка

Текущий архив: 2004.03.14;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.019 c
14-43773
raptorus
2004-01-23 13:57
2004.03.14
Уважаемые, Мастера, подскажите как создать файл помощи .hlp?


14-43847
Sergey13
2004-02-17 09:38
2004.03.14
Глюк или фича? Копирование файлов.


14-43861
ИМХО
2004-02-08 19:48
2004.03.14
Домены и айпишники


3-43265
Владий
2004-02-12 16:25
2004.03.14
Помогите найти причину - где у меня проблема, кроме головы?


3-43331
Layner
2004-02-16 11:52
2004.03.14
Преоборазование БД ACCESS *.mdb в файл *.mde, или как зищитить