Форум: "Сети";
Текущий архив: 2004.03.14;
Скачать: [xml.tar.bz2];
ВнизПересылка данных типа 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;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.011 c