![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Неправельный приём/передача данных [D6, WinXP]
Delpher_Gray © (2004-04-02 14:30:00)Така япроблема...
В программе сложные данные посылаются в обе стороны, и иногда бывают глюки...
Использую неблокирующиеся сокеты.
Сначала посылаю перфикс, содержащий парамерты:
1. Функция (что сделать с данными): integer
2. Размер данных идущих после префикса: integer
После посылки префикса посылаются сами данные, ну а после полного приёма программа решает что делать с принятыми данными, в зависимости от функции указанной в префиксе.
Вот и сам код приёма:
...
type
TPrefix = packed record
FuncCode: integer;
DataSize: integer;
end;
PPrefix = ^TPrefix;
...
var
PrefixReceive: boolean; // Режим приёма (префикс/данные)
PrefixOffset: integer; // Сколько байт префикса ещё не приняли
DataSize: integer; // Сколько байт данных ещё не приняли
Buf: array[0..1024] of Byte; // Буфер
MS: TMemoryStream; // Сюда записывается содержимое буффера
...
procedure TMain.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
BytesRead: integer;
begin
if PrefixReceive = true then
begin
BytesRead := Socket.ReceiveBuf(Buf[PrefixOffset], SizeOf(Prefix) - PrefixOffset);
Inc(PrefixOffset, BytesRead);
if PrefixOffset = SizeOf(Prefix) then
begin
DataSize := PPrefix(@Buf)^.DataSize;
StreamSize := DataSize;
Prefix.FuncCode := PPrefix(@Buf)^.FuncCode;
Prefix.DataSize := PPrefix(@Buf)^.DataSize;
if DataSize > 0 then
PrefixReceive := false // Если есть данные, то переводим программу в режим приёма данных
else
PrefixOffset := 0; // Если данных нет, то режим приёма префикса
end;
end else
begin
Application.ProcessMessages;
BytesRead := Socket.ReceiveBuf(Buf, Min(DataSize, SizeOf(Buf)));
MS.Write(Buf, BytesRead);
Dec(DataSize, BytesRead);
if DataSize = 0 then
begin
// Данные приняты - выполняем операции с MS
MS.Clear;
// Переводим сервер обратно в режим прёма префикса
PrefixReceive := true;
PrefixOffset := 0;
StreamSize := 0;
end;
end;
end;
А вот и код отсылки данных:
...
var
Prefix: TPrefix;
...
MS.LoadFromFile(...);
Prefix.FuncCode := 0;
Prefix.DataSize := MS.Size;
MS.Position := 0;
ClientSocket.Socket.SendBuf(Prefix, SizeOf(TPrefix));
ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);
...
Проблема заключается в том, что если я вызову несколько раз сразу (раз 5 в секунду) функцию передачи данных, то принемающий получит повреждённые данные !
В чём же дело !?
Заранее благодарен !
Delpher_Gray (2004-04-03 11:07:00) [1]Люди ау ! Помогите решить пролему...
Delpher_Gray (2004-04-02 20:49:00) [2]Уже начал читать...
Всё равно ты подскажи на конктерном примере как исплавить глюки то !? А там с помошью статьи я уже догонюсь что и как...
Digitman (2004-04-02 16:11:00) [3]
> Должно же поидеи
по какой такой "поидеи" ?! ты в состоянии хелп внимательно перечитать ? ты в состоянии проанализировать исх.текст компонента, благо он прямо перед носом у тебя ? ты в состоянии, прежде чем браться за отнюдь нетривиальную задачу, посетить http://book.itep.ru/7/sock_71.htmи проштудировать от корки до корки, прежде чем метаться ?
Delpher_Gray (2004-04-02 16:01:00) [4]Application.ProcessMessages - обязательно выкидывать!?
Просто когда получаю файл, программы подвисает :(
А событие OnWrite у меня возникает только один раз после подключения ! Должно же поидеи возникать каждый раз после посылки данных !?
Digitman (2004-04-02 15:52:00) [5]ты не понимаешь что ли ? тебе уже сказали - ВЫКИНЬ Application.ProcessMessages из своего текста ! и цикл выкинь !
ClientSocket.Socket.SendStream(MS);
все !!
и раньше чем получишь событие OnWrite даже и не дергайся что-либо еще посылать !
Verg (2004-04-02 15:51:00) [6]
> Delpher_Gray © (02.04.04 15:43) [3]
> Переделал код так:
> Send := ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);
> while Send < SizeOf(MS.Size) do
> Application.ProcessMessages;
Ты чего делаешь?! Опомнись!
Delpher_Gray (2004-04-02 15:43:00) [7]Переделал код так:
Send := ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);
while Send < SizeOf(MS.Size) do
Application.ProcessMessages;
Но всё равно ошибки !
Люди подскажите пожалуйста как переделать код, чтоб неглючило !?
Delpher_Gray (2004-04-02 15:43:00) [8]Сорри, в коде оишибка ! Не SizeOf(MS.Size), а MS.Size
Digitman (2004-04-02 15:13:00) [9]чудовищно
у меня уже язык отсох долдонить одно и то же
Verg (2004-04-02 14:49:00) [10]
> Application.ProcessMessages;
Выкинь эту строчку.
> ClientSocket.Socket.SendBuf(Prefix, SizeOf(TPrefix));
> ClientSocket.Socket.SendBuf(MS.Memory^, MS.Size);
Так делать нельзя.
WSAEWOULDBLOCK и все такое.
Где анализ результата ф-ций передачи данных?!