Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Сокеты [D7, WinXP]


Ivolg ©   (2006-08-04 19:51:00) 

Всем привет ! У меня возникла такая проблема с TServerSocket и TClientSocket... Вообщем при передаче какого-нибудь текста, принимается у меня он иногда с каракулями... Например посылаю: Client.Socket.SendText('90'), сервер принемает не число 90, а їРї9Р0ї... Помогите пожайлуста, в чем может быть проблема ? Спасибо...


Ivolg   (2006-08-07 13:08:00) [1]

Кто-нибдуь работал с этим компонентом ?


Ivolg   (2006-08-05 22:17:00) [2]

>Ketmar ©   (05.08.06 19:52) [12]

А этот компонент, только на локальном хосте работает ?


Ivolg   (2006-08-05 20:45:00) [3]

>Ketmar ©   (05.08.06 19:52) [12]

Спасибо ОГРОМНОЕ... Буду юзать )


Ketmar   (2006-08-05 19:52:00) [4]

TVyChat (было у Кабана -- http://cobans.net/). в Indy есть IRC. может, и ещё есть, с ходу вспоминать лень.


Ivolg   (2006-08-05 17:22:00) [5]

>Ketmar ©   (05.08.06 16:53) [10]

б, в - варианты мне походят, вопрос: где взять уже готовые компоненты для чата ?


Ketmar   (2006-08-05 16:53:00) [6]

> [9] Ivolg ©   (05.08.06 16:03)

а) не использовать сеть вообще;
б) сделать нормальный протокол и разбирать его;
в) использовать уже готовые компоненты для чата.


Ivolg   (2006-08-05 16:03:00) [7]

Можете посоветовать\подсказать как исправить эту проблему ?


Ketmar   (2006-08-05 09:44:00) [8]

> [7] Ivolg ©   (05.08.06 00:43)

тебе же пояснили. если ты отправил 100 байт, то совсем не обязательно клиент получит именно эти 100 и именно сразу. он может получить их любыми кусками. порядок сохранится, но не более.


Ivolg   (2006-08-05 00:43:00) [9]

>kami ©

Собственно эта статья мне ничем не помогла :\


kami   (2006-08-04 23:29:00) [10]

Ага, а вот тут уже нужно учитывать разбиение и склейку пакетов.
Пример - подключается клиент (при уже подключенных нескольких). Тогда начинается отправка всем известным полного списка ников (причем - с каждым новым ответом "Status\" данных в каждое гнездо посылается все больше и больше). Вот и получается, что при сравнительно большой занятости сети может быть следующее :
Сервер отправил "Ul\1;2;3...6;"и (после еще одного ответа клиента) "Ul\1;2;3;...6;7;".
При передаче эти два сообщения склеились, и на клиент пришло : "Ul\1;2;3...6;Ul\1;2;3;...6;7;", а могло и так (тоже к примеру) : "Ul\1;2;3...6;Ul\1;2"+ ";3;...6;7;".
А теперь посмотри, как это обрабатывают твои сервер с клиентами :) Никак.А нужно.
Почитай, например, http://www.delphimaster.ru/articles/sockets/index.html


Ivolg   (2006-08-04 23:00:00) [11]

Вот это кусок куда из моего чата, который передается с искажениями:

Серверная часть:


procedure TForm1.ServerClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
 S: string;
 i: Integer;
begin
   S:=Socket.ReceiveText;
   if  Copy(s,1,7)='Status\' then begin
   Delete(s,1,7);
   ListBox1.Items.Add(s); // Добавляем юзера в список
   S:='Ul\';
   for i:=0 to ListBox1.Items.Count-1 do
   S:=S+ListBox1.Items[i]+';'; // Разделяем каждый ник знаком ;
   for i:=0 to Server.Socket.ActiveConnections-1 do
   Server.Socket.Connections[i].SendText(S);
end;
end;
procedure TForm1.ServerClientConnect(Sender: TObject;
 Socket: TCustomWinSocket);
var
  i: Integer;
begin
    listbox1.Clear;
    for i:=0 to Server.Socket.ActiveConnections-1 do
    Server.Socket.Connections[i].SendText('Status\'); // Посылаем клиенту запрос на получение его ника
end;

end.


Клиентская часть:


procedure TForm1.ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
   S: String;
   it: TListItem;
begin
  S:=Socket.ReceiveText;
  if  Copy(s,1,3)='Ul\' then begin
  Delete(s,1,3);
  lv.Clear;
  while Pos(';',s) > 0 do begin
  it:=lv.Items.Add;
  it.Caption:=Copy(s,1,Pos(';',s)-1);
  Delete(s,1,Pos(';',s));
end;
end;
  if copy(s,1,7)='Status\' then begin
  delete(s,1,7);
  client.Socket.SendText('Status\'+edit1.Text); // Посылаем серверу свой ник
end;
end;


Когда когда заходят больше 3-4 клиентов в чат, то у одних показывается что юзеров 6-8, у других получается такая вещь:

User
User
User
Ul/User
User
Ul/User
User
User

Иного даже вместо Ников, добовляются всякие каракули...


kami   (2006-08-04 20:56:00) [12]

Забыл архи-сложный код :)
procedure TForm1.FormCreate(Sender: TObject);
begin
 ss:=TServerSocket.Create(Self);
 ss.Port:=1256;
 ss.OnClientRead:=ssClientRead;
 ss.Active:=True;

 cs:=TClientSocket.Create(Self);
 cs.Address:='127.0.0.1';
 cs.Port:=1256;
 cs.Active:=True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 cs.Socket.SendText(Edit1.Text);
end;

procedure TForm1.ssClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
 Edit2.Text:=Socket.ReceiveText;
end;


Пытался как только мог - отправлял и много текста, и циклом, так и не смог добиться того, чтобы принялось что-то не то, что отправлял :)) (да и невозможно это, если не брать в расчет склейку и разбиение по пакетам)


kami   (2006-08-04 20:28:00) [13]

Только что (в пределах одного приложения) посмотрел - все передается без искажений.


Ivolg   (2006-08-04 20:13:00) [14]

>kami ©   (04.08.06 20:05) [1]

Как принимаешь, код давай.


Как обычно...


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
 Socket: TCustomWinSocket);
var
  Msg: String;
  I: Integer;
begin
  Msg:=Socket.ReceiveText;
  I:=StrToInt(Msg);
end;

end.


kami   (2006-08-04 20:05:00) [15]

Как принимаешь, код давай.


Наверх

Титульная страница Поиск, карта сайта Написать письмо