Не работает чат delphi

Добрый день! Написал локальный чат. Одно время он работал. После перемещения на флешку, клиент отправляет сообщение, а сервер не принимает
вот программа

В любой непонятной ситуации надо добавлять отладочный вывод куда-нибудь (файл, мемо, консоль, …), выводить все действия и переменные, разбираться по этому логу что происходит.

1 лайк

Я выводил в лейблы

Так и что вывело?)

В лейблы неудобно выводить, видимо получится просто какое-то последнее состояние, а не лог.

1 лайк

Я накинул программу можешь глянуть? Смотрел порты все чтобы были одинаковы у сервера и клиента. В лейблах все четко у сервера и клиента одинаковые порты. И подключиться клиент к правильному локальному адресу.

А причем тут порты?

Вывод портов это не лог.

https://ru.wikipedia.org/wiki/Файл_регистрации

Ведение протокола (протоколирование) — хронологическая запись с различной (настраиваемой) степенью детализации сведений о происходящих в системе событиях (ошибки, предупреждения, сообщения), обычно в файл. В абсолютном большинстве современных программ используются текстовые файлы протоколов (одно событие — одна строка), они легко генерируются программой и анализируются человеком. Как исключение, в интерактивных утилитах (командной строки) сообщения о событиях выводятся прямо на экран пользователю, однако и этот вывод при необходимости можно перенаправить в файл.

Исследование содержимого файла регистрации ошибок после возникновения неполадок часто позволяет понять их причины.

1 лайк

Как сделать протоколирование программы в делфи

я ж говорю

Например,

WriteLog('Connected to server') когда подключился к серверу, WriteLog('Connection failed, error: + errorText) если не подключился и т.п., где WriteLog — своя процедура принимающая строку и добавляющая ее в файл или мемо.

Надо смотреть документацию о том как эти компоненты (IdUDPClient, …) сообщают об ошибках: какие-то события, или исключения кидают, или еще как-то. И соответственно подписаться на события или ловить исключения в try except, и выводить их данные.


И с TCP наверно было бы проще отладкой заниматься, потому что см. отличия TCP и UDP.

1 лайк

У меня вот такой вот модуль параметры передаются аналогично функции format().
Ничего сверх естественного открываем файл пишем в него данные.

unit dcvLog;

interface

uses SysUtils;

type

  TLogMode=(
     LOG_NONE,     // В лог не пишется¤.
     LOG_COMMON,   // Обязательные записи в журнал.
     LOG_ERROR,    // Ошибки с выводом dlgBox.
     LOG_INFO,     // Сообщения для строки статуса
     LOG_Worning,  // Обработанные ошибки, никому не светим тихо пишем в лог файл
     LOG_DEBUG,    // Ошибки выводимые в отладчик
     LOG_Trace1,LOG_Trace2,LOG_Trace3,LOG_Trace4 // Трассы.
     );

  TLog=class
    FFile:TextFile;
    LogLevel:Integer; // Уровень лога, сообщения с 0<LogMode<=LogLevel  будут писаться в лог-файл;
    constructor Create;
    procedure OpenFile(PathName:String);
    procedure Write(Mode:TLogMode; Notice:String; Params:array of const);
    procedure WriteLn(Mode:TLogMode; Notice:String; Params: array of const);
  end;

var
  Log:TLog;

implementation

{ TLog }

constructor TLog.Create;
begin
System.AssignFile(FFile,'Log.txt');
System.Rewrite(FFile);
end;

procedure TLog.OpenFile(PathName: String);
begin

end;

procedure TLog.Write(Mode: TLogMode; Notice: String;
  Params: array of const);
begin
if Ord(Mode)<Log.LogLevel then
   System.Write(FFile,Format(Notice,Params));
end;

procedure TLog.WriteLn(Mode: TLogMode; Notice: String;
  Params: array of const);
begin
Write(Mode, Notice+#13#10, Params);
end;

begin
Log:=TLog.Create;
Log.LogLevel:=9;
end.

И вот так вот использую.

function OpenDriver(var Index:Integer):Boolean;
const
 StrSize=255;
var
  DevNum:Integer;
  szDeviceName:String;
  szDeviceVersion:String;
  Ret:Boolean;
  pszDeviceName:PChar;
  pszDeviceVersion:PChar;

begin
  Log.WriteLn(LOG_Debug, 'VFW OpenDriver Params.Index=%d', [Index]);

  if Index>=10 then Index:=0;

  // Цикл является элементом устойчивости.
  for DevNum:=Index to 9 do
    begin
    GetMem(pszDeviceName,StrSize);
    GetMem(pszDeviceVersion,StrSize);
    FillChar(pszDeviceName[0], StrSize, 0);
    FillChar(pszDeviceVersion[0], StrSize, 0);
    Ret:=capGetDriverDescription(DevNum, pszDeviceName,
            StrSize, pszDeviceVersion,
            StrSize);
    szDeviceName:=pszDeviceName;
    szDeviceVersion:=pszDeviceVersion;
    FreeMem(pszDeviceName);
    FreeMem(pszDeviceVersion);

    if (Ret) then
        begin
        Log.WriteLn(LOG_Info, 'VFW Driver',[]);
        Log.WriteLn(LOG_Info, 'Num=%d', [DevNum]);
        Log.WriteLn(LOG_Info, 'DeviceName=%s', [szDeviceName]);
        Log.WriteLn(LOG_Info, 'DeviceVersion=%s', [szDeviceVersion]);
        Index:=DevNum; // Если открылся не тот что просили.
        Break;
        end;
    end;
end;


function CreateCapHandle(var WindowHandle:HWND):Boolean;
begin
  WindowHandle:= capCreateCaptureWindow('VFW capture window', WS_TILED, 0, 0, 0, 0, HWND(HWND_MESSAGE), 0);
  if (WindowHandle=0) then
     begin
       Log.WriteLn(LOG_ERROR, 'Could not create capture window.',[]);
       Result:=False;
     end;
end;

1 лайк

:confusedparrot:

1 лайк

попытался так:

procedure TForm1.Timer2Timer(Sender: TObject);
begin
Form1.Memo1.Text:= WriteLog('Connected to server');
Form1.Memo1.Text:= WriteLog('Connection failed, error:' + 'errorText');
end;

вот так:

procedure TForm1.Timer2Timer(Sender: TObject);
begin
Form1.Memo1.Lines.Text:= WriteLog('Connected to server');
Form1.Memo1.Lines.Text:= WriteLog('Connection failed, error:' + 'errorText');
end;

и еще так:

procedure TForm1.Timer2Timer(Sender: TObject);
begin
Form1.Memo1.Lines.Add(WriteLog('Connected to server')) ;
Form1.Memo1.Lines.Add(WriteLog('Connection failed, error:' + 'errorText'));
end;

Во всех случаях ошибка:

О том что не знает что такое WriteLog.

1 лайк

как сделать чтобы WriteLog вводила в мемо

procedure WriteLog(Value:string);
begin
Form1.Memo1.LineAdd(Value);
end;

Вам надо разобраться с областью видимости переменных.

Посмотрел ваш код. Ух жесть.
У вас куча форм куча серверов и у всех один и тот же адрес!
А ещё у вас в коде события Server_OnClick и Server_OffClick не назначены на кнопки.

1 лайк

Да один адрес, но разные порты. Раньше назначены были потом удалил. У меня все переменные глобальные, так проще пользоваться, а отдельный юнит зачем?

У вас несколько форм, у каждой формы свой юнит. В принципе на серверном коде у вас так и сделано два юнита и один инди сервер и этот юнит подкючев в первый. А на клиентском коде тоже два юните и не связаны и на каждой форме по инди-серверу правда в коде один закомментированы.
Соответственно подумал что у вас проблемы в этом месте.
Тем более это могла быть одна из причин почему у вас с memo не получалось.

unit Unit2;
...
uses unit1; // если не подключить, то будет ошибка.
...
procedure WriteLog(Value:string);
begin
unit1.Form1.Memo1.LineAdd(Value);
end;

А вообще лучше пишите, что пробовали сделать и что не получилось. Тогда мне и другим будет проще вам ответить.

1 лайк

думал на счет тсп сервера:
но он выдает такую ошибку:
image
ввожу свой внешний айпи адрес

был вариант с TSP server однако выло хуже чем UDP вариант с TSP server тоже выложил

Чем хуже-то? Наоборот лучше, сразу сам вывел ошибку о том, что не удалось подключиться.

Почему?

1 лайк

Ну потому, что удалось перемещения нормально все работало и все удавалось. А на TSP так и не удалось нечего дельного сделать.

Ну потому что на TSP до того как я начал программировать его были большие надежды чем на UDP