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

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

Вернуться   Форум программистов > C/C++ программирование > C++ Builder
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 31.05.2011, 19:58   #1
AlexCODER23
Пользователь
 
Аватар для AlexCODER23
 
Регистрация: 27.12.2010
Сообщений: 17
Вопрос TClientSocket переподключение при разрыве связи

Здравствуйте! Мне нужно организовать переподключение клиента к серверу при разрыве связи.
Сначала работал со статическим clientsocket'ом, но он отказывался перепокдлючаться при ошибке (а без нее не обходится разрыв), поэтому я стал создавать его динамически. Нужно, чтобы он при разрыве уничтожился и создался новый экземпляр.
Вот код инициализации:
Код:
void TForm1::InitSocket()
{
client = new TClientSocket(Form1);
client->Active=false;
client->Host=servadr;
client->Port=2393;
client->OnConnect=clientConnect;
client->OnConnecting=clientConnecting;
client->OnDisconnect=clientDisconnect;
client->OnError=clientError;
client->OnRead=clientRead;
}
Затем на кнопке
Код:
InitSocket();
client->Open();
Все работает, корректно общается с сервером, но когда начинаю обрабатывать ошибку....
Код:
void __fastcall TForm1::clientDisconnect(TObject *Sender,
      TCustomWinSocket *Socket)
{
client->Free();
InitSocket();
client->Open();
}
Вылетает это:
Windows socket error: Сделана попытка выполнить операцию на объекте, не являющемся сокетом (10038), on API "closesocket"
(кикаю с сервера, я знаю что это не "естественный разрыв" но даже на этом этапе появились ошибки)

Помогите разобраться, пожалуйста

Я так понимаю, это из-за того, что я некорректно создаю новый экземпляр/освобождаю старый ???
AlexCODER23 вне форума Ответить с цитированием
Старый 31.05.2011, 20:04   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вы конечно молодец, обьект уничтожили, и потом еще пытаетесь с ним работать.

не надо никаких Free
просто открйте сокет снова и все.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 31.05.2011, 20:07   #3
AlexCODER23
Пользователь
 
Аватар для AlexCODER23
 
Регистрация: 27.12.2010
Сообщений: 17
По умолчанию

Проблема как раз в том, что я не могу его снова открыть. А точнее я пытаюсь открыть его 3 раза (попытки с таймаутом), это видно под отладчиком, но никаких изменений не происходит. Сервер даже не регестрирует подключение
(дисконнект зарегестрировал, т.е. путаницы быть не может, такого соединения с ним нет)
AlexCODER23 вне форума Ответить с цитированием
Старый 31.05.2011, 20:09   #4
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

ошибок у сокета дофига может быть, у TClientSocket есть вроде как OnError событие, если ему назначить обработчик, возможно, Exception не будет выскакивать.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 31.05.2011, 20:13   #5
AlexCODER23
Пользователь
 
Аватар для AlexCODER23
 
Регистрация: 27.12.2010
Сообщений: 17
По умолчанию

Цитата:
Сообщение от veniside Посмотреть сообщение
ошибок у сокета дофига может быть, у TClientSocket есть вроде как OnError событие, если ему назначить обработчик, возможно, Exception не будет выскакивать.
Раньше, когда был статический сокет, делал так:
Код:
void __fastcall TForm1::clientError(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
ErrorCode=0;
Socket->Close();
}


в OnDisconnect

for (int i=0;i<trycount;i++)
{
if (!client->Socket->Connected)
{
try
{
client->Open();
sleep(3000);}
}
catch(...)
{ShowMessage("Error");}
}
}
исключений не возникало, но и подключения тоже)
(к сожалению целиком кода не осталось, т.к. переписал уже все) )

Последний раз редактировалось AlexCODER23; 31.05.2011 в 20:16.
AlexCODER23 вне форума Ответить с цитированием
Старый 31.05.2011, 20:15   #6
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> исключений не возникало, но и подключения тоже)

а зачем там Socket->Close()?
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 31.05.2011, 20:17   #7
AlexCODER23
Пользователь
 
Аватар для AlexCODER23
 
Регистрация: 27.12.2010
Сообщений: 17
По умолчанию

> а зачем там Socket->Close()?
А как иначе? Я же должен как то пережить разрыв))


---------------------
тему ап )

Последний раз редактировалось AlexCODER23; 31.05.2011 в 20:25.
AlexCODER23 вне форума Ответить с цитированием
Старый 31.05.2011, 20:38   #8
AlexCODER23
Пользователь
 
Аватар для AlexCODER23
 
Регистрация: 27.12.2010
Сообщений: 17
По умолчанию

посоветуйте что-нибудь конкретное) все равно можно же как то и с динамическим сокетом это провернуть
хотя мне уже без разницы как) лиж бы работало)
AlexCODER23 вне форума Ответить с цитированием
Старый 02.06.2011, 06:04   #9
AlexCODER23
Пользователь
 
Аватар для AlexCODER23
 
Регистрация: 27.12.2010
Сообщений: 17
По умолчанию

Кто-нибудь может объяснить, как после разрыва осуществить подключение???
AlexCODER23 вне форума Ответить с цитированием
Старый 02.06.2011, 11:22   #10
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

боже, да что ж там такого сложного. Вот, ровно 7 минут потратил, работает как часы:

Код:
unit Unit1;

interface

uses
  Windows, Forms, Classes, Controls, StdCtrls, ScktComp, ExtCtrls;

type
  TForm1 = class(TForm)
    btnRestartServer: TButton;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure btnRestartServerClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
    procedure clnOnError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
    procedure clnOnDisconnect(Sender: TObject; Socket: TCustomWinSocket);
  public
    { Public declarations }
    srv: TServerSocket;
    cln: TClientSocket;
    //
    needReconnect: boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

// --  --
procedure TForm1.FormCreate(Sender: TObject);
begin
  srv := TServerSocket.create(self);
  srv.Port := 12345;
  srv.Open();
  //
  cln := TClientSocket.create(self);
  cln.Host := 'localhost';
  cln.Port := 12345;
  //
  cln.OnError := clnOnError;
  cln.OnDisconnect := clnOnDisconnect;
  //
  cln.Open();
end;

// --  --
procedure TForm1.btnRestartServerClick(Sender: TObject);
begin
  srv.Close();
  srv.Open();
end;

// --  --
procedure TForm1.clnOnError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  needReconnect := true;
end;

// --  --
procedure TForm1.clnOnDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  needReconnect := true;
end;

// --  --
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (needReconnect) then begin
    //
    needReconnect := false;
    cln.Open();
  end;
end;

end.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 02.06.2011 в 11:26.
veniside вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Переподключение ADSL соединения Qami Общие вопросы Delphi 2 09.05.2010 20:21
Автоматическое переподключение интернета sibirnik Свободное общение 0 20.01.2010 13:01
Добавление записи через список в связанную таблицу(при связи с Access) megaten БД в Delphi 5 17.05.2009 15:57
Java приложение для перезванивания при разрыве hook Общие вопросы по Java, Java SE, Kotlin 4 29.04.2008 20:10