Добрый день! Написал локальный чат. Одно время он работал. После перемещения на флешку, клиент отправляет сообщение, а сервер не принимает
вот программа
В любой непонятной ситуации надо добавлять отладочный вывод куда-нибудь (файл, мемо, консоль, …), выводить все действия и переменные, разбираться по этому логу что происходит.
Я выводил в лейблы
Так и что вывело?)
В лейблы неудобно выводить, видимо получится просто какое-то последнее состояние, а не лог.
Я накинул программу можешь глянуть? Смотрел порты все чтобы были одинаковы у сервера и клиента. В лейблах все четко у сервера и клиента одинаковые порты. И подключиться клиент к правильному локальному адресу.
А причем тут порты?
Вывод портов это не лог.
https://ru.wikipedia.org/wiki/Файл_регистрации
Ведение протокола (протоколирование) — хронологическая запись с различной (настраиваемой) степенью детализации сведений о происходящих в системе событиях (ошибки, предупреждения, сообщения), обычно в файл. В абсолютном большинстве современных программ используются текстовые файлы протоколов (одно событие — одна строка), они легко генерируются программой и анализируются человеком. Как исключение, в интерактивных утилитах (командной строки) сообщения о событиях выводятся прямо на экран пользователю, однако и этот вывод при необходимости можно перенаправить в файл.
Исследование содержимого файла регистрации ошибок после возникновения неполадок часто позволяет понять их причины.
Как сделать протоколирование программы в делфи
я ж говорю
Например,
WriteLog('Connected to server')
когда подключился к серверу, WriteLog('Connection failed, error: + errorText)
если не подключился и т.п., где WriteLog
— своя процедура принимающая строку и добавляющая ее в файл или мемо.
Надо смотреть документацию о том как эти компоненты (IdUDPClient, …) сообщают об ошибках: какие-то события, или исключения кидают, или еще как-то. И соответственно подписаться на события или ловить исключения в try except
, и выводить их данные.
И с TCP наверно было бы проще отладкой заниматься, потому что см. отличия TCP и UDP.
У меня вот такой вот модуль параметры передаются аналогично функции 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;
попытался так:
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.
…
как сделать чтобы WriteLog
вводила в мемо
procedure WriteLog(Value:string);
begin
Form1.Memo1.LineAdd(Value);
end;
Вам надо разобраться с областью видимости переменных.
Посмотрел ваш код. Ух жесть.
У вас куча форм куча серверов и у всех один и тот же адрес!
А ещё у вас в коде события Server_OnClick и Server_OffClick не назначены на кнопки.
Да один адрес, но разные порты. Раньше назначены были потом удалил. У меня все переменные глобальные, так проще пользоваться, а отдельный юнит зачем?
У вас несколько форм, у каждой формы свой юнит. В принципе на серверном коде у вас так и сделано два юнита и один инди сервер и этот юнит подкючев в первый. А на клиентском коде тоже два юните и не связаны и на каждой форме по инди-серверу правда в коде один закомментированы.
Соответственно подумал что у вас проблемы в этом месте.
Тем более это могла быть одна из причин почему у вас с memo не получалось.
unit Unit2;
...
uses unit1; // если не подключить, то будет ошибка.
...
procedure WriteLog(Value:string);
begin
unit1.Form1.Memo1.LineAdd(Value);
end;
А вообще лучше пишите, что пробовали сделать и что не получилось. Тогда мне и другим будет проще вам ответить.
думал на счет тсп сервера:
но он выдает такую ошибку:
ввожу свой внешний айпи адрес
был вариант с TSP server однако выло хуже чем UDP вариант с TSP server тоже выложил
Чем хуже-то? Наоборот лучше, сразу сам вывел ошибку о том, что не удалось подключиться.
Почему?
Ну потому, что удалось перемещения нормально все работало и все удавалось. А на TSP так и не удалось нечего дельного сделать.
Ну потому что на TSP до того как я начал программировать его были большие надежды чем на UDP