Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.03.2012, 19:19   #1
Лубышев
Участник клуба
 
Аватар для Лубышев
 
Регистрация: 23.07.2007
Сообщений: 1,054
Вопрос Обмен данными клиент/сервер, delphi

тут http://www.programmersforum.ru/showthread.php?t=190283 уже обсуждалась тема, но кажется я шел не по правильному пути.

Я пишу сейчас что то вроде протокола общения клиента с сервером. Юзаю сокеты (кстати на Delphi пишу).
Так как у меня была проблема в слипании пакетов я решил использовать фиксированную длинну. на данный момент 44 байта. По сути это набор из integer переменных 11 штук))) - пока хватает. (для корректной отправки integer переменной надо 4 байта), но иногда мне надо передавать не только числа но и маленькие текстовые сообщения.

Я завел два типа данных

Код:
//44
type mes=record
id:integer;//идентификатор команды
ed:integer;
values:array[0..9] of integer;
end;


//44
type mestext=record
id:integer;//идентификатор команды
ed:integer;
pd:integer;
text:string[16];
text2:string[16];
end;
Они одинакового размера получаются. (44 байта)

Отправка сообщения происходит примерно так:
Код:
var a:mestext;
...
for i:=0 to form1.Server.Socket.ActiveConnections-1 do
    form1.Server.Socket.Connections[i].SendBuf(a,44);

// или так

var b:mes;
...
for i:=0 to form1.Server.Socket.ActiveConnections-1 do
    form1.Server.Socket.Connections[i].SendBuf(b,44);
ловлю сообщение так:
Код:
var a:mestext;
b:mes;
...
Socket.ReceiveBuf(a,44); //прочитать пакет
//или Socket.ReceiveBuf(b,44); //прочитать пакет
Вот тут у меня и возникает загвозка: как определить какой пакет был отправлен: первого или второго типа
в первом числе в обоих типах данных у меня хранится идентификатор комманды - по нему и определяется какой это пакет и как с ним оперировать
Лучший способ здесь - прочитать пакет в обе переменные и уже потом в зависимости от идентификатора юзать первую или вторую переменную. но как прочитать пакет в обе переменные одновременно?
пробовал так:
Код:
var a:mes;
b:mestext;
buf:TmemoryStream;
begin
buf:=TmemoryStream.Create;
Socket.ReceiveBuf(buf,44);
buf.Read(a,44);
buf.Position:=0;//или seek
buf.Read(b,44);
//buf.Destroy;//если тут уничтожить - то программа вообще критует полюбому
Писано по д'Эльфийски
Лубышев вне форума Ответить с цитированием
Старый 12.03.2012, 11:42   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Хочешь честно?
Я забил на устаревшие компоненты сокетов и использую ИНДИ. В ней решена проблема разреза пакетов.
P.S. по крайней мере я передавая сотни килобайтов символов в сообщении на разрывы не нарывался.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.03.2012, 18:29   #3
Лубышев
Участник клуба
 
Аватар для Лубышев
 
Регистрация: 23.07.2007
Сообщений: 1,054
По умолчанию

ну там опять же такая же проблема встанет. я конечно могу передавать не 44 байта а 88 склеив два типа данных в один но зачем посылать полупустые пакеты
Писано по д'Эльфийски
Лубышев вне форума Ответить с цитированием
Старый 12.03.2012, 19:04   #4
Лубышев
Участник клуба
 
Аватар для Лубышев
 
Регистрация: 23.07.2007
Сообщений: 1,054
По умолчанию

Может как то так получится
Код:
procedure TForm1.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var buf:TmemoryStream;
size:integer;
begin
buf:=Tmemorystream.Create;
size:= Socket.ReceiveLength;
Socket.ReceiveBuf(buf,size);
form1.Client2.Socket.SendBuf(buf,size);
хотя я думаю что кританет. я что то видел в одной из тем сдесь что лучше в качестве буффера глобальную переменную юзать - тока ее над наверное постоянно чистить после передачи пакета... ото будет забиваться

тьфу ты. не в ту тему написал
Писано по д'Эльфийски
Лубышев вне форума Ответить с цитированием
Старый 12.03.2012, 20:20   #5
Slym
Участник клуба
 
Регистрация: 07.12.2011
Сообщений: 1,025
По умолчанию

в слипании проблем нет... протокол гавно
кто тебе мешает размер структур передавать передавать

если сервер структуры не разгребает а только как ретранслятор то посылай размер первым делом

Код:
var
  len:integer;
  Data:PChar;

begin
  Socket.ReceiveBuf(len,SizeOf(len));
  GetMem(Data,len);
  Socket.ReceiveBuf(Data^,len);

  for i:=0 to form1.Server.Socket.ActiveConnections-1 do
begin
    form1.Server.Socket.Connections[i].SendBuf(len,SizeOf(len));
    form1.Server.Socket.Connections[i].SendBuf(Data^,len);
end;
разгребание структуры можно так

type
pmestext=^mestext;
mestext=record
id:integer;//идентификатор команды
ed:integer;
pd:integer;
text:string[0..0];
end;

pmestext(Data)^.ed
Не стесняемся, плюсуем!
Slym вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Требуется написать программу на Delphi 7 - Обмен данными между MySQL и Excel yaskin Фриланс 9 08.11.2011 11:31
Delphi 7, клиент-сервер, СУБД ПрограммеррР Помощь студентам 0 12.05.2010 19:36
Builder и Delphi клиент сервер maldun Общие вопросы C/C++ 0 26.04.2010 15:15
Обмен данными между двумя формами в Delphi NecroSlider Помощь студентам 2 30.07.2009 11:52
Создать клиент и сервер. Delphi SPQR Работа с сетью в Delphi 4 12.11.2007 12:48