Конференция "Сети" » Интернет-чат. На копонентах TServerSocket \TClientSocket [D7, WinXP]
 
  • Maloj2007 © (13.12.08 21:30) [0]
    Доброго времени суток ув. форумчане!

    У меня к вам вопрос, есть код (ниже приведен) при отправке сообщения иногда оно по непонятной мне причине приходит на сервер дважды.
    Подскажите что не так с кодом.

    Код сервера:

    type TReadMsg = packed record
       User:array [0..127] of char;
       Msg:array [0..1023] of char;
     end;
    type TSendMsg = packed record
       ID:Byte;
       User:array [0..127] of char;
       Msg:array [0..1023] of char;
     end;
    ...
    procedure TMainForm.ServerClientRead(Sender: TObject; Socket: TCustomWinSocket);
    var
     CMD:Byte;
     I:integer;
     AllMsgRead:TReadMsg;
     AllMsgSend:TSendMsg;
    begin
     Socket.ReceiveBuf(CMD,SizeOf(CMD));
     case CMD of
     125:
       begin
         Socket.ReceiveBuf(AllMsgRead,SizeOf(AllMsgRead));
         AllMsgSend.ID:=125;
         StrLCopy(AllMsgSend.User,AllMsgRead.User,SizeOf(AllMsgSend.User));
         StrLCopy(AllMsgSend.Msg,AllMsgRead.Msg,SizeOf(AllMsgSend.Msg));
         for I := 0 to Server.Socket.ActiveConnections-1 do
           Server.Socket.Connections[i].SendBuf(AllMsgSend,SizeOf(AllMsgSend));
       end;
     end;
    end;



    Код клиента:

    type TReadMsg = packed record
       User:array [0..127] of char;
       Msg:array [0..1023] of char;
     end;
    type TSendMsg = packed record
       ID:Byte;
       User:array [0..127] of char;
       Msg:array [0..1023] of char;
     end;
    ...
    procedure TMainForm.ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    var
     CMD:byte;
     AllMsg:TReadMsg;
    begin
     Socket.ReceiveBuf(CMD,SizeOf(CMD));
     case CMD of
       125:
       begin
         Socket.ReceiveBuf(AllMsg,SizeOf(AllMsg));
       end;
     end;
    end;

    procedure TMainForm.BtSendClick(Sender: TObject);
    var
     AllMsg:TSendMsg;
    begin
     AllMsg.ID:=125;
     StrLCopy(AllMsg.Msg,Pchar(Msg),SizeOf(AllMsg.Msg));
     StrLCopy(AllMsg.User,Pchar(UserName),SizeOf(AllMsg.User));
     Client.Socket.SendBuf(AllMsg,SizeOf(AllMsg));
     //вот это сообщение отправляется 2 раза
    end;

  • Сергей М. © (13.12.08 22:04) [1]

    >  Client.Socket.SendBuf(AllMsg,SizeOf(AllMsg));
    >  //вот это сообщение отправляется 2 раза


    Где же два, когда всего один (и то не факт что нарантированно отправляется) ?
  • Maloj2007 © (13.12.08 22:25) [2]

    > >  Client.Socket.SendBuf(AllMsg,SizeOf(AllMsg));>  //вот
    > это сообщение отправляется 2 разаГде же два, когда всего
    > один (и то не факт что нарантированно отправляется) ?

    Вот и я думал что 1. Тут привел сокрашенно часть кода, без проверки и обработки исключений.
    Во время отправки сообщения с клиента оно уходит 2 может даже 3 раза уйти. Соответственно и приходит на сервер несколько сообщений. Причем количество сообщений и частоту дублирования (дублирует не всегда но часто) делфя определяет как-то рамдомно. В чем загвоздка может быть?
  • Сергей М. © (14.12.08 19:32) [3]

    > с клиента оно уходит 2 может даже 3 раза уйти


    Если ты нажал кнопку 1 раз, то оно будет отправлено один раз.
  • Сергей М. © (14.12.08 19:35) [4]

    > SendBuf


    > ReceiveBuf


    Это функции !!!
  • Slym © (14.12.08 20:27) [5]
    Maloj2007 ©   (13.12.08 22:25) [2]
    вкорне неверная работа с сокетом:
    ReceiveBuf - функция что подразумевает результат
    Врочитать может меньше чем "заказано", а проверки нет
    тоже самое касается SendBuf
  • Сергей М. © (14.12.08 21:02) [6]
    +

    > тоже самое касается SendBuf


    В 1-ю очередь касается !
  • behemot © (22.07.09 11:56) [7]
    В операторе case указано 125, хотя массив типа char.
  • Vitaly B (15.07.10 10:42) [8]
    Сначала вызывается BtSendClick. Первое сообщние отправлено. Пришел ответ с сервера. Клиент вызвал процедуру ClientRead. И если ответ 125, то еще раз посылается сообщение: Socket.ReceiveBuf(AllMsg,SizeOf(AllMsg));
  • Anatoly Podgoretsky © (15.07.10 13:30) [9]
    > Maloj2007  (13.12.2008 21:30:00)  [0]

    Ты проверил это точками останова?
    И что это BtSendClick? Если это кнопка то ее надо запрещать то окончания
    посылки, а то у некоторых руки трясутся.
  • maks787 (15.01.11 17:52) [10]
    Ни пояснений, ничего, для новечка это просто полная жо..а
  • Сергей М. © (15.01.11 19:07) [11]

    > maks787   (15.01.11 17:52) [10]


    А что, новичкам противопоказано читать справку  ?)
  • CFIFok (10.07.11 13:21) [12]
    Программа представляет собой простейший интернет чат, написанный на Delphi 7. Информация передается между компьютерами посредством протокола UDP. Все, что требуется, это знать IP компьютера получателя. Программа работает без хостингов и серверов, как по интернет соеденению так и по обычной LAN.

    http://letitbit.net/download/41513.4d79df999d8d54351a5677cf6c35/Internet_Chat.rar.html
  • FireMan_Alexey © (10.07.11 18:14) [13]
    Есть мысль, может стоит создать в разделе статьи нормальный пример "Чата", чтобы потом можно было посылать "по дальше"!
    А то это уже 1000000-й вопрос "Скачал пример чата на компонентах, а почему у меня не работает как я себе представляю?" или "Почему я записываю в буфер строку, а она не вся доходит? Или я же в параметрах ф-ции ReceiveBuf указал размер ххх, а в строке какие-то БЯКИ" :)
    P.S. Админ прости за ОФФ! ;)
 
Конференция "Сети" » Интернет-чат. На копонентах TServerSocket \TClientSocket [D7, WinXP]
Есть новые Нет новых   [134435   +13][b:0][p:0.002]