![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
В общем такая проблема...
Есть Сервер и Клиент, которые перебрасываются между собой динамическими массивами. Отправка и принятие у сервера работает отлично, но вот клиент не может нормально принять массив... Точнее он его принимает, но либо программа сама закрывается, либо при закрытии Клиента выдает ошибку "invalid pointer operation". Для начала я проверил, что может быть я не правильно работаю с массивом, но нет, обращение к данным в этом массиве происходит без ошибок... Ниже привожу код программы: Код Клиента при принятии: Код:
procedure TForm1.CSRead(Sender: TObject; Socket: TCustomWinSocket);
begin
try
ct:=0;
ct:=(CS.Socket.ReceiveLength div 4)div 768;
SetLength(Adm,ct);
CS.Socket.ReceiveBuf(Adm[0],CS.Socket.ReceiveLength);
List.Clear;
for i:=0 to High(Adm) do
List.Items.Add(Adm[i].Name+' '+'('+Adm[i].ip+')'+Adm[i].roll);
finally
SetLength(Adm,0);
end;
end;Код:
SetLength(Mass,j); for f:=0 to High(Mass) do Begin Mass[f].Name:=NameHost[f]; Mass[f].ip:=IP[f]; Mass[f].roll:=Roll[f]; end; SS.Socket.Connections[i].SendBuf(Mass[0],SizeOf(Mass)*Length(Mass)*768); // i-задается в другом месте SetLength(Mass,0); в общем когда приходит массив размерностью 1, то выдает "invalid pointer operation" послы выхода из программы. а когда приходит массив более 1 строк, то программа вылетает с ошибкой "access violation ...". Помомгите люди добрые ![]() Последний раз редактировалось Admin, 07.06.2013 в 09:32. |
|
#2
|
||||
|
||||
|
а почему буферу устанавливается размер в 3072 раза меньше, чем запрашивается данных?
|
|
#3
|
|||
|
|||
|
Цитата:
Цитата:
SizeOf(Mass) = 4 Умножаем на количество элементов в массиве, за тем умножаем на размер 3-х строк (768) в каждом элементе этого массива Цитата:
Последний раз редактировалось Ioanwar, 07.06.2013 в 09:28. |
|
#4
|
||||
|
||||
|
Код:
1. ct:=(CS.Socket.ReceiveLength div 4)div 768; 2. SetLength(Adm,ct); 3. CS.Socket.ReceiveBuf(Adm[0],CS.Socket.ReceiveLength); 2. массиву Adm назначается этот размер 3. из сокета запрашиваются данные в массив Adm с максимальным размером равным ReceiveLength, т.е. в 3072 раза больше, чем сам массив |
|
#5
|
|||
|
|||
|
Цитата:
где Adm[0]- адрес, а CS.Socket.ReceiveLength задаю размер буфера. т.е. по идее второй параметр ReceiveBuf я указываю размер буффера а не размер массива |
|
#6
|
||||
|
||||
|
как Adm объявлен?
|
|
#7
|
|||
|
|||
|
Цитата:
Код:
Type
Pac=packed record
Name,ip,roll:String[255];
end;
Var
Adm:array of Pac;Mass на Сервере объявлен так же. |
|
#8
|
|||
|
|||
|
почему вот так
Код:
ct:=(CS.Socket.ReceiveLength div 4)div 768; а не вот так Код:
ct:=CS.Socket.ReceiveLength div sizeof(Adm[0]); |
|
#9
|
|||
|
|||
|
Цитата:
Следовательно, что бы мне найти количество элементов в массиве заранее, я делаю так. И следовательно, потом массив принимается точно такой же, и с таким же размером. |
|
#10
|
||||
|
||||
|
ReceiveLength не будет равно количеству переданных байт! сумма нескольких последовательных ReceiveLength будет. и SizeOf(Mass) в отправке лишнее и 4 в приеме.
Последний раз редактировалось NumLock, 07.06.2013 в 10:08. |
| Этот пользователь сказал Спасибо NumLock за это полезное сообщение: | ||
Ioanwar (07.06.2013)
| ||
|
#11
|
|||
|
|||
|
Цитата:
|
|
#12
|
|||
|
|||
|
Цитата:
|
|
#13
|
|||
|
|||
|
Цитата:
NumLock спасибо тебе, вроде работает. Если что отпишусь) |
|
#14
|
||||
|
||||
|
эмуляция передачи данных через сокет. для примера выделения памяти на передающей и принимающей сторонах:
Код:
type
TMyRec = record
Id: String[255];
Name: String[255];
IP: String[255];
end;
var
Arr: array of TMyRec;
sz: Integer;
Buffer: Pointer;
begin
SetLength(Arr, 10); // 10 elements
Arr[5].Id:='5';
Arr[5].Name:='NumLock';
Arr[5].IP:='127.0.0.1';
sz:=Length(Arr)*SizeOf(TMyRec); // size arr in bytes = element count * size of element
// element size = size of TMyRec
ShowMessage(IntToStr(sz));
Buffer:=GetMemory(sz); // get memory for simulate socket (Buffer)
MoveMemory(Buffer, @Arr[0], sz); // transfer data to "socket"
SetLength(Arr, 0); // clear source arr
SetLength(Arr, sz div SizeOf(TMyRec)); // (sz div SizeOf(TMyRec)) how elements?
MoveMemory(@Arr[0], Buffer, sz); // receive data from "socket", sz .aka. ReceiveLength
ShowMessage(Arr[5].Id+' '+Arr[5].Name+' '+Arr[5].IP);
FreeMemory(Buffer);
end; |
|
#15
|
|||
|
|||
|
Цитата:
![]() Теперь могу спокойно поспать, а потом по новой за работу. Спасибо тебе еще раз NumLock. Последний раз редактировалось Ioanwar, 07.06.2013 в 10:42. |