// aplSocketClient.cpp : implementation file
//
#include "stdafx.h"
#include "aplSocketTransport.h"
#include "commands.h"
#include "WaitDlg.h"
#include "ServerStopDlg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CRITICAL_SECTION m_OperateListClients;

// Макросы или просто выполняют работу с критическими секциями, или 
// выводят в стандартный лог сообщения о работе с секциями
// в отладочном режиме требует рядом с определением критической секции 
// определения переменной типа long с именем ИМЯ_СЕКЦИИ+"_COUNTER"
// для переключения в отдладочный режим в настройках проекта вкладка C++
// должен быть определен макрос _DEBUG_LOG_CRTITICAL_SECTION

#ifdef _DEBUG_LOG_CRTITICAL_SECTION 

extern long m_IsBlockedInternalBuf_COUNTER;

extern long m_ManageOperate_COUNTER;
extern long LstenServList_COUNTER;

#endif

#pragma intrinsic( memcpy,memset)

/*
class SOCKET_TRANSPORT_API CaplSocketClientE
{
	friend CTransportWaitDlg;
	// Attributes
protected:
	bool m_operation_in_progress;
	ASC_ERROR_CODES m_LastAscError;
	int m_LastWsaError;
	CServerStopDlg* m_server_stop_dlg;
	AFX_THREADPROC m_renew_function;
	LPVOID m_parameter_renew_function;
	CString m_class_info;

public:
	bool m_NeedAutoDelete;
	bool m_ServerStopping;
	bool m_hide_mode;

	DWORD m_LastReadyData;
	LPVOID m_upper_container;

	// Operations
public:
	CaplSocketClientE();
	CaplSocketClientE(LPCTSTR ip, UINT port);
	virtual ~CaplSocketClientE();

	bool GetHostName(CString &name);
	// Если ip соединение с сервером есть - возвращает ip адрес, упакованный в 4 байта иначе 0
	long GetCompIp();

	void SetBreak(bool state);
	bool IsBreak();
	bool IsBufferFull();

	// Overrides
public:

	// Работа над ошибками
	CString	GetDescriptionLastError();
	ASC_ERROR_CODES GetLastAscError();
	int GetLastWsaError();	
	void SetLastAscErrors(ASC_ERROR_CODES AscError);	

	// установка времен'ных параметров
	bool SetTimeOut(DWORD timeout_waitdlg,DWORD timeout_my_receive=TIMEOUT_RECEIVE);
	bool SetTimerParam(HWND timer_target,DWORD timer_id,DWORD timer_interval);

	// Соедниение с сервером по адресу ip и порту port
	// если prev_ping==true то перед соединением сервер пингуется и при отсутствии ответа соединение
	// не устанавливается (чтобы не тормозить с выключенными серверами)
	bool Connect(LPCTSTR ip, UINT port, bool prev_ping=true);
	void Disconnect();

	bool Call(void** data, DWORD &length, void* lpBuf2=0, DWORD nBufLen2=0, bool can_break=true, bool pause_wait_dlg=true, bool wait_answer=true);
	void ClearInternalData();
	void SetErrProtocolMess(const CString &err_protocol_mess){m_err_protocol_mess=err_protocol_mess;}


	void SetRenewFunction(AFX_THREADPROC renew_function, LPVOID parameter_renew_function);
	// Получение состояний
	bool IsConnected();
	//	bool IsTimeOutDlg();
	bool IsWaitDlg();
	bool IsActiveWaitDlg();
	bool IsOperated();
	// установка режима отображения управляющих диалогов
	void SetManageMode(DWORD manage_mode);
	void SetWaitDlgText(LPCTSTR waitdlg_text);
	bool IsReadyData();

	// При вызове OnClose будет вызываться эта внешняя функция (если она определена)
	void (__cdecl *external_close_funct)(LPVOID param);

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CaplSocketClient)
public:
	//}}AFX_VIRTUAL

	// Generated message map functions
	//{{AFX_MSG(CaplSocketClient)
	// NOTE - the ClassWizard will add and remove member functions here.
	//}}AFX_MSG

	// Implementation
protected:

	SOCKET m_hSocket;
	WSAEVENT m_hEventObject;


	// номер обращения к серверу
	DWORD m_num_send;
	int MyReceive(void* data,DWORD length);
	int MySend(const void* lpBuf1, DWORD nBufLen1,const void* lpBuf2=0, DWORD nBufLen2=0,const void* lpBuf3=0, DWORD nBufLen3=0,bool is_throw=true);
	// в зависимости от length читает из канала данные (letgth>0) или команду (==0)
	// возвращает true при обработке данных и false в случае команды
	// !!! На все ошибки вызывает исключения типа ASC_ERROR_CODES
	bool FullRead(DWORD length);

	// параметры таймера интерфейса
	DWORD m_timer_interval;
	DWORD m_timer_id;
	HWND m_timer_target;
	// указатель на класс транспорта у сервера
	DWORD m_server_class;
	// время до появления диалога "выполняется операция.Ждите"
	DWORD m_waitdlg_time;
	// текст на диалоге "ждите"
	CString m_waitdlg_text;
	// максимальное время для выполнения операции сервером (0-не ограничено)
	DWORD m_timeout_call;
	// максимальное время для ожидания приема (receive) (0-по умолчанию- 50 000 милисекунд)
	DWORD m_timeout_my_receive;
	// есть ли связь с сервером
	bool m_IsConnected;
	// срочно прерываем текущую операцию сервера
	bool m_flag_break;
	// операция чтения/ожидания данных прервана.
	bool m_is_buffer_full;

	//
	bool ProcessedCommand(DWORD command);

	CString m_err_protocol_mess;

	BYTE* m_InternalData;
	DWORD m_size_InternalData;
	CRITICAL_SECTION m_IsBlockedInternalBuf;
	// режим отображения управляющих диалогов
	DWORD m_manage_mode;

	// Параметры, по которым мы соединялись с сервером
	CString m_server_ip;
	UINT m_server_port;

	CTransportWaitDlg* m_wt_dlg;
	// если true сокет уже разорван. Любая передача данных отменяется
	bool m_halt;

	CRITICAL_SECTION m_ManageOperate;
private:
	void InitVar();
};



void Add2ListE(CaplSocketClientE* client)
{
// 	EnterLogCriticalSection(&m_OperateListClients);
// 	if(client!=0)
// 	{
// 		list_existed_clients.Add(client);
// 	}
// 	LeaveLogCriticalSection(&m_OperateListClients);
}

void RemoveFromListE(CaplSocketClientE* client)
{
// 	EnterLogCriticalSection(&m_OperateListClients);
// 	if(client!=0)
// 	{
// 		list_existed_clients.Remove(list_existed_clients.Find(client));
// 	}
// 	LeaveLogCriticalSection(&m_OperateListClients);
}

void CALLBACK TimerProcClientE(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
// 	int i;
// 	CaplSocketClientE* client;
// 	//CString str;
// 	//DWORD tick=GetTickCount();
// 	int buf=0,size=4;
// 	if(nIDEvent==timer_ptr)
// 	{
// 		EnterLogCriticalSection(&m_OperateListClients);
// 		for(i=0;i<list_existed_clients.GetSize();i++)
// 		{
// 			client=list_existed_clients[i];
// 			if(client==0)continue;
// 			if(client->IsReadyData()){
// 				size=client->m_LastReadyData;
// 				//str.Format("По таймеру блокировки ID_TIMER_BLOCK пытаемся прочитать из канала остаток данных; всего нужно получить %i байт",size);
// 
// 				//LogDebugMessageIfDef(CString(str));
// 				/** /
// 				if(client->Receive(&buf,4,MSG_PEEK)!=-1){
// 					//LogDebugMessageIfDef(CString("Начали получать данные"),(long)0,_T(__FILE__),__LINE__);
// 				}else{
// 					LogDebugMessageIfDefG("Не удалось прочитать данные из канала! Возможна потеря данных... Или данные уже кем-то прочитаны");
// 				}
// 				/** /
// 			}
// 		}
// 		LeaveLogCriticalSection(&m_OperateListClients);
// 		
// 	}
}


void SetUnBlockTimerE()
{
// 	timer_ptr= KillTimer(0,ID_TIMER_BLOCK);
// 	timer_ptr= SetTimer(0,ID_TIMER_BLOCK,2000,TimerProcClient);
}


/////////////////////////////////////////////////////////////////////////////
// CaplSocketClientE

CaplSocketClientE::CaplSocketClientE()
{  

//#define __FUNCTION__ "CaplSocketClientE::CaplSocketClientE"
	
	InitVar();
// 	Add2List(this);

}

CaplSocketClientE::CaplSocketClientE(LPCTSTR ip, UINT port)
{

//#define __FUNCTION__ "CaplSocketClientE::CaplSocketClientE 2"
	
	InitVar();
	Connect(ip,port);
// 	Add2List(this);
}

CaplSocketClientE::~CaplSocketClientE()
{

//#define __FUNCTION__ "CaplSocketClientE::~CaplSocketClientE"
	
//	RemoveFromList(this);
	if(m_wt_dlg!=0){
		m_wt_dlg->m_pClient=0;
		delete m_wt_dlg;// а вот здесь удалить надо обязательно
	}
	m_wt_dlg=0;

	if(m_server_stop_dlg!=0){
		if(m_server_stop_dlg->m_hWnd!=0)
			m_server_stop_dlg->EndDialog(0);
		delete m_server_stop_dlg;
		m_server_stop_dlg=0;
	}
	ClearInternalData();
	Disconnect();

	if(m_hEventObject!=NULL )CloseHandle(m_hEventObject);


	DeleteLogCriticalSection(&m_IsBlockedInternalBuf);
	DeleteLogCriticalSection(&m_ManageOperate);
}

void CaplSocketClientE::InitVar()
{

//#define __FUNCTION__ "CaplSocketClientE::InitVar"
	
//	SetUnBlockTimer();

	InitializeLogCriticalSection(&m_IsBlockedInternalBuf);
	InitializeLogCriticalSection(&m_ManageOperate);
	m_InternalData=0;
	m_renew_function=0;
	m_parameter_renew_function=0;
	m_size_InternalData=0;
	m_IsConnected=false;
	m_timer_target=0;
	m_timer_id=0;
	m_timer_interval=0;
#ifdef _DEBUG
	m_timeout_call=TIMEOUT_WAIT_NODIALOG; //в отладочных целях...
	m_waitdlg_time=TIMEOUT_BEFORE_WAITDIALOG;	// в отладочных целях...
#else
	m_timeout_call=TIMEOUT_WAIT_NODIALOG;
	m_waitdlg_time=TIMEOUT_BEFORE_WAITDIALOG;
#endif
	m_timeout_my_receive=TIMEOUT_RECEIVE;
	m_flag_break=false;
	m_is_buffer_full=false;
	m_operation_in_progress=false;
	m_manage_mode=MANAGE_WAITDLG;
	m_waitdlg_text="";
	m_server_class=0;

	m_server_ip="";
	m_server_port=0;
	m_num_send=0;
	external_close_funct=0;
	m_upper_container=0;
	m_server_stop_dlg=0;
	m_NeedAutoDelete=false;
	m_ServerStopping=false;
	m_halt=false;
	m_wt_dlg=0;
	m_hide_mode=false;
	m_LastReadyData=0;

	m_hSocket = INVALID_SOCKET;
	m_hEventObject = NULL;

	
	m_err_protocol_mess = APL_T("Сервер работает с устаревшей версией транспортного протокола. Обновите сервер приложений!\n");
	m_err_protocol_mess += APL_T(" Дальнейшая работа невозможна");

	m_class_info.Format("CaplSocketClientE " POINTER_FORMAT "; create in thread " THREAD_FORMAT ,this,GetCurrentThreadId());

	LogDebugMessageIfDef(_T("Inited"));
}


// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CaplSocketClientE, CSocket)
	//{{AFX_MSG_MAP(CaplSocketClientE)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif	// 0

/////////////////////////////////////////////////////////////////////////////
// CaplSocketClientE member functions


bool CaplSocketClientE::IsOperated()
{

//#define __FUNCTION__ "CaplSocketClientE::IsOperated"
	
	bool retval;
	LogDebugMessageIfDef(_T("IsOperated"));
	EnterLogCriticalSection(&m_IsBlockedInternalBuf);
	retval=m_operation_in_progress;
	LogDebugMessageIfDef(retval?"m_operation_in_progress==true":"m_operation_in_progress==false");
	LeaveLogCriticalSection(&m_IsBlockedInternalBuf);
	return retval;
}


bool CaplSocketClientE::Connect(LPCTSTR ip, UINT port, bool prev_ping)
{

//#define __FUNCTION__ "CaplSocketClientE::Connect"
	
	m_LastAscError=ASC_NO_ERROR;
	m_LastWsaError=0;
	if(m_IsConnected){
		LogDebugMessageIfDef( APL_T("Connect - уже соединены..."));
		m_LastAscError=ASC_ALREADY_CONNECTED;return false;
	}
	LogDebugMessageIfDef( APL_T("Connect - соединяемся..."));


// 	CString str;
// 	DWORD command,command2;
// 	int nRead;
// 	char* buf=0;
// 	try{
// 	//	CSocket::Create();
// 		m_hSocket =  socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
// 		if (m_hSocket == INVALID_SOCKET)
// 		{
// 			APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 		}
// 		m_hEventObject = WSACreateEvent();
// 		//WSAEventSelect( m_hSocket, m_hEventObject, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
// 		WSAEventSelect( m_hSocket, m_hEventObject, FD_READ | FD_WRITE | FD_OOB | FD_CLOSE);
// 
// 
// 		if(prev_ping)
// 		{
// // 			HINSTANCE hinst_top=AfxGetApp()->m_hInstance;
// // 			TransportPing2(ip,hinst_top);
// 			if(TransportPing(ip)==FALSE){
// 				APL_TRANSPORT_THROW(ASC_HOST_INACCESSIBLE);
// 			}
// 		}
// 		if(CSocket::Connect(ip, port))
// 		{
// 			m_server_ip=ip;
// 			m_server_port=port;
// 			// Запрашиваем статус сервера. Фактически серверу идут два нуля
// 			command=0;
// 			command2=CMDGetServerStatus;
// 			if(MySend(&command,4,&command2,4)==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 			// Получаем подтверждение соединения
// 			nRead = MyReceive(&command, 4);
// 			if(nRead ==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 			if(nRead!=4 || command!=0){
// 				APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);
// 			}
// 			nRead = MyReceive(&command, 4);
// 
// 			if(nRead ==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 			if(nRead!=4){
// 				APL_TRANSPORT_THROW( ASC_MISSED_RECEIVE_SIZE);
// 			}
// 			switch (command){
// 			case CMDConnectionOK:
// 				if(m_manage_mode!=MANAGE_ABSENT)AfxMessageBox(m_err_protocol_mess,
// 					MB_OK | MB_ICONERROR);
// 				APL_TRANSPORT_THROW(ASC_ERROR_MISSED_VERSION);
// 				
// 			case CMDConnectionOKNew:
// 				nRead = MyReceive(&command, 4);// c номером версии
// 				if(nRead ==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 				nRead = MyReceive(&command2, 4);// с указателем на сокет
// 				if(nRead ==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 
// 				if(command < VERSION_NUMBER){
// 					if(m_manage_mode!=MANAGE_ABSENT)AfxMessageBox(m_err_protocol_mess,
// 						MB_OK | MB_ICONERROR);
// 					APL_TRANSPORT_THROW(ASC_ERROR_MISSED_VERSION);
// 					
// 				}else if(command > VERSION_NUMBER){
// 					if(m_manage_mode!=MANAGE_ABSENT)AfxMessageBox("Версия транспортного протокола сервера приложений более новая, чем версия транспортного протокола клиента.\n"
// 						"Обновите клиента!"
// 						" Дальнейшая работа невозможна",
// 						MB_OK | MB_ICONERROR);
// 					APL_TRANSPORT_THROW(ASC_ERROR_MISSED_VERSION);
// 				}
// 				m_server_class=command2;
// 				m_IsConnected=true;
// 				break;
// 			default:
// 				ProcessedCommand(command);
// 				APL_TRANSPORT_THROW(ASC_ERROR_PROCESSED);
// 			}
// 			// посылаем команду...
// 			command=0;
// 			// на получение версии
// 			command2=CMDGetVersionBuffer;
// 			if(MySend(&command,4,&command2,4)==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 			// ждем ответа - сначала длина буфера
// 			nRead = MyReceive(&command, 4);
// 			if(nRead==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 			if(0 == command  || 0 == nRead){
// 				APL_TRANSPORT_THROW(ASC_ERROR_MISSED_VERSION);
// 			}
// 			if(command>100)APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);// проверка на дурака
// 			buf=new char[command];
// 			nRead = MyReceive(buf,command);
// 			if(nRead==SOCKET_ERROR)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
// 			if((DWORD)nRead!=command){
// 				APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);
// 			}
// 			nRead=strlen(VERSION_INFO);
// 			if(memcmp(buf,VERSION_INFO,(DWORD)nRead<command?nRead:command)!=0){
// 				APL_TRANSPORT_THROW(ASC_ERROR_MISSED_VERSION);
// 			}
// 			delete buf;buf=0;
// 			
// 		}else{
// 			APL_TRANSPORT_THROW(ASC_ERROR_IN_CONNECT);
// 		}
// 	}
// 	catch(SaplErrorDescription error)
// 	{
// 		m_LastWsaError=WSAGetLastError();
// 		m_LastAscError=(ASC_ERROR_CODES)error.m_err_code;
// 		if(buf!=0)delete buf;buf=0;
// 		this->Close();
// 
// 		LogDebugMessageIfDefFormat1("Not connected - error %i",error);
// 		return false;
// 	}
// 	LogDebugMessageIfDef(APL_T("Connect - готово");
	return true;
}


bool CaplSocketClientE::IsConnected()
{

//#define __FUNCTION__ "CaplSocketClientE::IsConnected"
	
	return m_IsConnected;
}

void CaplSocketClientE::Disconnect()
{

//#define __FUNCTION__ "CaplSocketClientE::Disconnect"
/*	
	// посылаем команду...
	DWORD command=0,command1=CMDDisconnect;
	try{
		if(m_IsConnected){
			MySend(&command,4,&command1,4);
		}
	}
	catch(SaplErrorDescription error)
	{
		// Ничего не делаем - главное, ловим исключения
		m_LastAscError=(ASC_ERROR_CODES)error.m_err_code;
		m_LastWsaError=WSAGetLastError();
	}
	//LogDebugMessageIfDef(_T("Disconnect");
		
	//AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
	this->Close();
	m_IsConnected=false;
	m_renew_function=0;
	m_parameter_renew_function=0;
	
	LogDebugMessageIfDef(_T("Disconnected");
}

bool CaplSocketClientE::Call(void** data,DWORD &length,
							void* lpBuf2, DWORD nBufLen2,bool can_break,bool pause_wait_dlg,bool wait_answer)
{

//#define __FUNCTION__ "CaplSocketClientE::Call"
	m_LastAscError=ASC_NO_ERROR;
	m_LastWsaError=0;
	bool ret_val=true;
	DWORD tick_limit=0,call_time_limit=0;
	int res_sock=0;
	DWORD count=0;
	
	if(*data==0){
		m_LastAscError=ASC_MISSED_PARAM;
		return false;
	}
/*	

	try{
		LogDebugMessageIfDef(_T("Call");
		EnterLogCriticalSection(&m_IsBlockedInternalBuf);
		// Отработка таймера в этой же нити критической секцией не ловится
		if(m_operation_in_progress){
			if(m_operation_in_progress){
				LogDebugMessageIfDef(APL_T("m_operation_in_progress==true, возвращаем ASC_OPERATION_IN_PROGRESS");
				LeaveLogCriticalSection(&m_IsBlockedInternalBuf);
				m_LastAscError=ASC_OPERATION_IN_PROGRESS;
				// если выйти по исключению, то блок catch прервет процедуру на сервере и покурочит данные
				return false;
			}
		}
		ClearInternalData();
		m_operation_in_progress=true;
		m_num_send++;
	
		LogDebugMessageIfDefFormat2("•Call: Sending to server %i BYTEs (Send N %i)",length,m_num_send);
		LogDebugMessageIfDefFormat1(" m_manage_mode:%s ",(m_manage_mode==MANAGE_WAITDLG?"MANAGE_WAITDLG":""));
		
		// отправляем данные серверу по возможности одной пачкой
		res_sock=MySend(&length,4,*data,length,lpBuf2,nBufLen2);
		if(res_sock==SOCKET_ERROR){
			APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
		}
		if(!wait_answer){
			LogDebugMessageIfDef(APL_T("wait_answer==false, выходим");
			LeaveLogCriticalSection(&m_IsBlockedInternalBuf);
			return true;
		}

		// Устанавливаем таймер (если он задан)
		if(m_timer_target!=0 && m_timer_id!=0 && m_timer_interval!=0){
			SetTimer(m_timer_target,m_timer_id,m_timer_interval,0);
		}
		// timeout || waitdlg
		if(m_manage_mode==MANAGE_WAITDLG){
			tick_limit=GetTickCount();
			if(pause_wait_dlg){
				tick_limit+=m_waitdlg_time;	
			}else{
				tick_limit+=-100;	
			}
		}
		// сколько всего можно ждать
		call_time_limit=GetTickCount();
		call_time_limit+=m_timeout_call;	

		// чтобы предыдущий мусор не гадил
		m_is_buffer_full=false;
		SetBreak(false);
		count=0;

		LogDebugMessageIfDef(_T("Call - Wait server's answer");

		while(true){
			if(m_is_buffer_full){
				// блин, кто-то уже принял данные с сервера...
				break;
			}
			if(m_LastAscError!=ASC_NO_ERROR){
				break;
			}
			
			// Пытаемся прочитать из канала
			//AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();

			res_sock = CAsyncSocket::Receive(&length, 4);
			LogDebugMessageIfDefFormat2(" Call: CAsyncSocket::Receive return %i (Send N %i)",res_sock,m_num_send);
	
			if(res_sock == SOCKET_ERROR){

				// опять с сервера ничего не пришло...
				// определяем, нет ли проблем с каналом?
				m_LastWsaError=WSAGetLastError();
				if(0!= m_LastWsaError && WSAEWOULDBLOCK != m_LastWsaError)
					// ага что-то серьезное, ответ мы уже не дождемся
					APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
				if(call_time_limit!=0 && call_time_limit<GetTickCount() ){
					// ничего мы не дождемся
					APL_TRANSPORT_THROW(ASC_TIMEOUT);
					break;
				}

				if(tick_limit!=0 && tick_limit<GetTickCount() && !m_hide_mode){
					// пора показывать диалоги ожидания или прерывания
					if(m_manage_mode==MANAGE_WAITDLG){
						// Диалог "Сервер производит обработку данных"(с бочками"
						LogDebugMessageIfDef(_T("m_manage_mode==MANAGE_WAITDLG");

						m_wt_dlg=new CTransportWaitDlg(AfxGetMainWnd());
						if(m_waitdlg_text!="")m_wt_dlg->m_txt=m_waitdlg_text;
						m_wt_dlg->m_pClient=this;
						m_wt_dlg->m_can_break=can_break;
					}
					if(m_wt_dlg!=0){
						// наступил таймаут
						// чтобы память очистить, даже когда this удалят
						CTransportWaitDlg* wt_dlg=0;
						wt_dlg=m_wt_dlg;
						CaplSetResourceHandle res_handle(module_inst);
						int res=wt_dlg->DoModal();
						res_handle.RestoreHadle();
						if(wt_dlg->IsNeedDelete()){
							// при обработке оконной процедуры диалога была вызвана
							// функция OnClose клиента. Класс клиента скорей всего удален, так что
							// надо срочно бежать
							// только диалог удалим
							if(wt_dlg!=0){delete wt_dlg;wt_dlg=0;}
							LogDebugMessageIfDef(_T("Extra 1!\n");
							return false;
						}else{
							if(m_wt_dlg!=0){delete m_wt_dlg;m_wt_dlg=0;}
						}
						if(m_NeedAutoDelete){
							// при обработке оконной процедуры диалога была вызвана
							// функция OnClose клиента. Класс клиента скорей всего удален, так что
							// надо срочно бежать
							// только диалог удалим
							delete this;
							LogDebugMessageIfDef(_T("Extra 2!\n");
							return false;
						}

					}
					if(m_is_buffer_full){
						// так, пока пользователь ждал, данные получены OnReceive-ом. Выходим из цикла
						break;
					}
				}
				if(IsBreak()){
					LogDebugMessageIfDef(_T("flag break");
					SetBreak(false);
					APL_TRANSPORT_THROW((ASC_ERROR_CODES)ASC_BREAK_CALL);
					break;
				}
				LogDebugMessageIfDef(_T("peek message");
				
				// Тайм аута нет, данные не пришли. Надоть обработать текущие 
				// сообщения из очереди приложения
				if(m_LastWsaError == WSAEWOULDBLOCK){
					LogDebugMessageIfDef(_T("PumpMessage");
					// Сначала CSocket-ные обработки
					//AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
					PumpMessages(FD_READ);

					if(m_is_buffer_full){
						// при обработке FD_READ  данные получены OnReceive-ом
						LogDebugMessageIfDef(APL_T("при обработке FD_READ корректно отаботал OnReceive");
						break;
					}
				}
				// сообщения таймера и перерисовки
				MSG msg; 
				if(global_process_wm_paint)
				{
					while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT,
						PM_REMOVE|  PM_NOYIELD)) 
						DispatchMessage(&msg);
				}
				while (::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER,
					PM_REMOVE|  PM_NOYIELD)) 
					DispatchMessage(&msg);
				count++;

				LogDebugMessageIfDefFormat1(" End cicle %i ",count);
			}else{
				// так, что-то прочиталось
				LogDebugMessageIfDefFormat2(" CAsyncSocket::Receive get data with length %i (Send N %i)",length,m_num_send);

				if(res_sock!=4){
					// Тут ошибка, а что делатть?
					APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);
				}
				if(FullRead(length)){
					// это были данные
				}
			}
		}
		// в любом случае длина данных должна быть правильной
		if(m_is_buffer_full){
			*data=m_InternalData;			
			length=m_size_InternalData;
		}
		if(m_LastAscError==ASC_OPERATION_IN_PROGRESS){
			m_LastAscError=ASC_NO_ERROR;
		}
	}
	catch(SaplErrorDescription error)
	{
		m_LastWsaError=WSAGetLastError();
		LogDebugMessageIfDef(APL_T("Call: Исключение! ");
		if(m_InternalData!=0){
			delete m_InternalData;
			m_size_InternalData=0;
			m_InternalData=0;
		}
		m_operation_in_progress=false;
		LeaveLogCriticalSection(&m_IsBlockedInternalBuf);
		ret_val=false;
		m_LastAscError=(ASC_ERROR_CODES)error.m_err_code;


		if(ASC_BREAK_CALL==error.m_err_code && m_server_class!=0){
			LogDebugMessageIfDef(_T("Break on WaitDlg. Send break 2 server with second channel");
			// пошлем-ка серверу черную метку
			CaplSocketClientE black_cli;
			int command,command2,command3;
			int nRead;
			if(black_cli.Connect(m_server_ip,m_server_port)){
				command=0;// 0 - признак команды
				command2=CMDBreakOperation; // код команды
				command3=m_server_class; // дополнительные данные
				black_cli.MySend(&command,4,&command2,4,&command3,4,false);
				// ждем ответ, как прервалось
				nRead=black_cli.MyReceive(&command,4);
				if(nRead!=4 || command!=0){
					// ошибка при приеме флага команды или пришел не флаг команды!
					command=CMDCriticalError;
				}
				nRead=black_cli.MyReceive(&command,4);
				if(nRead!=4){
					// ошибка при приеме теперь уже команды!
					command=CMDCriticalError;
				}
				// ну и все
				black_cli.Disconnect();
				switch (command){
				case CMDBreakOk:
					break;
				case CMDCriticalError:
				default:
					LogDebugMessageIfDef(_T("Break work not correctly!");
					if(m_manage_mode!=MANAGE_ABSENT)AfxMessageBox(	"Прервать операцию не удалось. Возможно,\n"
									"пользователь ORACLE не имеет необходимых прав\n"
									"На сервере поставлен флаг завершения операции,\n"
									"но он сработает только после завершения SQL запроса\n"
									);
					break;
				}
			}
		}else{
			LogDebugMessageIfDefFormat3(" Error in Call! ASC_Error %i WSAErrcode %i (Send N %i)",error,m_LastWsaError,m_num_send);
		}
		if(error.m_err_code==ASC_ERROR_IN_SOCKET){
			if(TEST_DISCONNECT(m_LastWsaError))
			{
				// или сеть рухнула, или удаленных хост, в общем, кирдык соединению
				error.m_err_code=ASC_ERROR_SOCKET_CLOSE;
			}
		}
	}
	if(m_timer_target!=0 && m_timer_id!=0 && m_timer_interval!=0){
		KillTimer(m_timer_target,m_timer_id);
	}
	if(m_wt_dlg!=0){
		delete m_wt_dlg;
		m_wt_dlg=0;
	}
* /
	return ret_val;
}

/*
void CaplSocketClientE::OnClose(int nErrorCode) 
{

//#define __FUNCTION__ "CaplSocketClientE::OnClose"
	
	LogDebugMessageIfDef(_T("OnClose");
	if(m_server_stop_dlg!=0){
		m_server_stop_dlg->EndDialog(0);
	}
	if(m_wt_dlg!=0){
		m_wt_dlg->m_pClient=0;
	}
	m_halt=true;
//	if(!m_IsConnected)return;

	if(external_close_funct!=0){
		if(m_wt_dlg!=0){
			m_wt_dlg->SetNeedDelete(true);
			m_wt_dlg->SendMessage(WM_QUIT);
			m_wt_dlg=0;
		}
		external_close_funct(m_upper_container);
		// после вызова этой функции нельзя вызывать переменные-члены класса!
	}else{
		m_wt_dlg=0;
	}
}


void CaplSocketClientE::OnSend(int nErrorCode) 
{

//#define __FUNCTION__ "CaplSocketClientE::OnSend"
	
	LogDebugMessageIfDef(_T("OnSend");
}
	
void CaplSocketClientE::OnReceive(int nErrorCode) 
{

//#define __FUNCTION__ "CaplSocketClientE::OnReceive"
	
	// TODO: Add your specialized code here and/or call the base class
	
	DWORD length;
	int nRead;
	try{
		nRead = MyReceive(&length, 4);

		LogDebugMessageIfDefFormat1(" On receive: length data is %i BYTE",length);

		if(SOCKET_ERROR==nRead){
			LogDebugMessageIfDefFormat2(" Error receiving! Errcode %i (Send N %i)",m_LastWsaError,m_num_send);
			APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
		}
		FullRead(length);
	}
	catch(SaplErrorDescription error)
	{
		m_LastAscError=(ASC_ERROR_CODES)error.m_err_code;
		m_LastWsaError=WSAGetLastError();
		if(m_operation_in_progress)
		{
			throw(error);
		}
	}
	LogDebugMessageIfDef(_T("OnReceive end")
}
* /
bool CaplSocketClientE::FullRead(DWORD length)
{

//#define __FUNCTION__ "CaplSocketClientE::FullRead"
	
	//LogDebugMessageIfDefFormat1(" Full read getting... %i BYTE",length);
/*
	DWORD position=0;
	DWORD command=0;
	int res_sock;
	DWORD max_num_err=0;
	DWORD cur_limit=0;
	
	if(length<0){
		APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);
	}else if(length==0){
		// с сервера команда
		res_sock = MyReceive(&command, 4);

		//LogDebugMessageIfDefFormat2(" Full read getting command %i from server! (res_sock %i)",command,res_sock);
		
		if(res_sock==SOCKET_ERROR)
			APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
		if(res_sock!=4){
			// опять ошибка
			APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);
		}else{
			ProcessedCommand(command);
			LogDebugMessageIfDef(APL_T("Full read : обработали команду. Выходим из FullRead")
			return false;
		}
	}
	
	if(m_InternalData!=0){
		delete m_InternalData;
	}
	m_size_InternalData=0;
	m_InternalData=new BYTE[length];
	do{
		// приходить может по частям!
		res_sock = MyReceive(m_InternalData+position, length-position);
		
		//LogDebugMessageIfDefFormat1(" Full Read принял %i BYTE",res_sock);
		
		if(res_sock==SOCKET_ERROR){
			
			LogDebugMessageIfDefFormat2(" Ошибка сокета при приеме данныx; errcode %i; N %i",m_LastWsaError,max_num_err);
			
			if(max_num_err>100)APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
			max_num_err++;
			continue;
		}
		if(res_sock+position>length)APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE);
		if(res_sock+position==length)
			break;
		position+=res_sock;
	}while(true);
	if(m_operation_in_progress){
		m_is_buffer_full=true;
		m_size_InternalData=length;
	}else{
		// с сервера пришли непонятные данные. Очищаем буфер
		if(m_InternalData!=0){
			delete m_InternalData;
			m_InternalData=0;
		}
	}
* /
	//LogDebugMessageIfDefFormat1(" Full read get %i BYTE",length);
	return true;
}


int CaplSocketClientE::MyReceive(void *data, DWORD length)
{

//#define __FUNCTION__ "CaplSocketClientE::MyReceive"

	CaplTimeMeter timeout_receive;

	int nResult=0;
	if(m_halt)return -1;
	m_LastWsaError=0;
/*		
	LogDebugMessageIfDefFormat1(" Myreceive getting %i BYTE...",length);
	
	// И смиренно ждем ответа
	while ((nResult = CAsyncSocket::Receive(data, length)) == SOCKET_ERROR){
		m_LastWsaError=WSAGetLastError();
		if ( WSAEWOULDBLOCK==m_LastWsaError)
		{
			//			PumpMessages(FD_READ); Этот вызов здесь может привести к зацикливанию
		}
		else if(TEST_DISCONNECT(m_LastWsaError))
		{
			m_halt=true;
			LogDebugMessageIfDefFormat2((nResult==SOCKET_ERROR?" Myreceive get %i BYTE with errcode %i":" Myreceive get %i BYTE (%i)"),nResult,m_LastWsaError);
			return nResult;
		}	
		if(timeout_receive.CheckTimeOut(m_timeout_my_receive))
		{
			break;
		}
	}
	
	LogDebugMessageIfDefFormat2((nResult==SOCKET_ERROR?" Myreceive get %i BYTE with errcode %i":" Myreceive get %i BYTE (%i)"),nResult,m_LastWsaError);
* /	
	return nResult;
}


bool CaplSocketClientE::ProcessedCommand(DWORD command)
{

//#define __FUNCTION__ "CaplSocketClientE::ProcessedCommand"
/*	
	int percentage=0;
	int dead_time=0;
	switch(command){
	case CMDTooManyClients:
		LogDebugMessageIfDef(_T("Command from server - CMDTooManyClients (5)!");
		APL_TRANSPORT_THROW( ASC_TOO_MANY_CLIENTS_ON_SERVER);
		break;
	case CMDErrorServerProcessed:
		LogDebugMessageIfDef(_T("Command from server - CMDErrorServerProcessed (10)!");
		APL_TRANSPORT_THROW(ASC_ERROR_PROCESSED_ON_SERVER);
		break;
	case CMDErrorReceiveData:
		LogDebugMessageIfDef(_T("Command from server - CMDErrorReceiveData (11)!");
		APL_TRANSPORT_THROW(ASC_MISSED_RECEIVE_SIZE_ON_SERVER);
		break;
	case CMDErrorMissedSocketType:
	case CMDErrorInitServer:
		LogDebugMessageIfDef(_T("Command from server - CMDErrorInitServer (12) or CMDErrorMissedSocketType (13)!");
		APL_TRANSPORT_THROW( ASC_ERROR_INIT_SERVER);
		break;
	case CMDSetProgress:
		LogDebugMessageIfDef(_T("Command from server - CMDSetProgress (21)");
		// Принимаем 4 байта - процент выполненного
		MyReceive(&percentage,4);
		LogDebugMessageIfDefFormat1("Параметр команды %i",percentage);
		if(m_wt_dlg!=0){
			m_wt_dlg->SetProgressRatio(percentage);
		}
		break;
	case CMDErrorMissedData:
		LogDebugMessageIfDef(_T("Command from server - CMDErrorMissedData (14)");
		break;
	case CMDRenewClientState:
		LogDebugMessageIfDef(_T("Command from server - CMDRenewClientState (26)");
		if(m_renew_function!=0){
			m_renew_function(m_parameter_renew_function);
		}
		break;
	case CMDDeadTime:
		LogDebugMessageIfDef(_T("Command from server - CMDDeadTime (25)");
		// Принимаем 4 байта - время ожидаемого выключения (в секундах)
		MyReceive(&dead_time,4);
		LogDebugMessageIfDefFormat1("Параметр команды %i",dead_time);
		m_ServerStopping=true;
		if(m_hide_mode && dead_time>=0)
		{
			dead_time=0;
			OnClose(0);
			return true;
		}
		if(m_server_stop_dlg!=0 && dead_time<0)
		{
			m_server_stop_dlg->CloseWindow();
			delete m_server_stop_dlg;
			m_server_stop_dlg=0;
			if(!m_hide_mode)AfxMessageBox("Завершение работы прервано. Работаем дальше");
		}
		else if(m_server_stop_dlg==0 && dead_time!=0)
		{
			m_server_stop_dlg=new CServerStopDlg();
			m_server_stop_dlg->MakeText(dead_time);
			m_server_stop_dlg->Create(IDD_SERVER_STOP_DIALOG,0);
		}
		if(m_server_stop_dlg!=0){
			if(m_server_stop_dlg->m_hWnd!=0){
				m_server_stop_dlg->SetStoppingTime(dead_time);
				m_server_stop_dlg->ShowWindow(SW_SHOW);
				m_server_stop_dlg->SetForegroundWindow();
			}
		}
		break;
	case CMDCriticalError:
		LogDebugMessageIfDef(_T("Command from server - CMDCriticalError (102)");
		// Принимаем 4 байта - дополнительный код ошибки
		MyReceive(&dead_time,4);
		APL_TRANSPORT_THROW( dead_time);
		break;

	default:
		break;
	}
* /
	return true;
}


int CaplSocketClientE::MySend(const void* lpBuf1, DWORD nBufLen1,const void* lpBuf2, DWORD nBufLen2,const void* lpBuf3, DWORD nBufLen3,bool is_throw)
{

//#define __FUNCTION__ "CaplSocketClientE::MySend"
	

	int ret=0;
/*
	u_long portion_size=MAX_PORTION_SIZE;
	u_long iterator_data=0,iterator_buf=0,length;
	char* buf=0;
	int i=0;

	int num_buf=0;
	DWORD sent=0;
	WSABUF data_bufs[3];
	if(lpBuf1==0 || nBufLen1==0){
		return -1;
	}
	if(m_halt)
	{
		return -1;
	}
/*
	data_bufs[0].buf=(char*)lpBuf1;
	data_bufs[0].len=nBufLen1;
	if(lpBuf2==0 || nBufLen2==0){
		num_buf=1;
		data_bufs[1].buf=(char*)0;
		data_bufs[1].len=0;
		data_bufs[2].buf=(char*)0;
		data_bufs[2].len=0;
	}else{
		data_bufs[1].buf=(char*)lpBuf2;
		data_bufs[1].len=nBufLen2;
		if(lpBuf3==0 || nBufLen1==0){
			num_buf=2;
			data_bufs[2].buf=(char*)0;
			data_bufs[2].len=0;
		}else{
			data_bufs[2].buf=(char*)lpBuf3;
			data_bufs[2].len=nBufLen3;
			num_buf=3;
		}
	}
	ret=WSASend(m_hSocket,data_bufs,num_buf,&sent,0,0,0);
	if(SOCKET_ERROR==ret){
		m_LastWsaError=WSAGetLastError();
		if(WSAEWOULDBLOCK==m_LastWsaError){
			return 0;
		}
		else if(TEST_DISCONNECT(m_LastWsaError))
		{
			m_halt=true;
			LogDebugMessageIfDefFormat1((" MySend don't post because errcode %i"),m_LastWsaError);
			return ret;
		}	
		else
		{
			if(WSAENOBUFS==m_LastWsaError){
				LogDebugMessageIfDefFormat2(" MySend: разбиваем %i буферов суммарной длиной %i на части",num_buf,nBufLen1+nBufLen2+nBufLen3);
				do{
					try{
						// Разбиваем на части и посылаем маленькими порциями
						sent=0;
						char* buf=0;
						buf=new char[portion_size];
						if(buf==0){
							// вот блин памяти совсем нет, даже на такой буфер...
							m_LastWsaError=WSAENOBUFS;
							APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
						}
						for(i=0;i<num_buf;i++){
							iterator_data=0;
							if(data_bufs[i].len==0){
								break;
							}
							do{
								length=(data_bufs[i].len-iterator_data)<(portion_size-iterator_buf)?
									(data_bufs[i].len-iterator_data):(portion_size-iterator_buf);
								memcpy((char*)(buf+iterator_buf),(char*)(data_bufs[i].buf+iterator_data),length);
								iterator_buf+=length;
								iterator_data+=length;
								if(iterator_buf==portion_size){
									// буфер полон. посылаем
									ret=Send(buf,iterator_buf);
									// буфер после посылки заполняем c начала
									iterator_buf=0;
									if(SOCKET_ERROR==ret){
										m_LastWsaError=WSAGetLastError();
										delete buf;
										APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
									}
									sent+=ret;
									if(iterator_data<data_bufs[i].len){
										// этот буфер данных еще не кончился
										continue;
									}
								}
								if(i==num_buf-1){
									// Этот буфер входных данных - последний
									ret=Send(buf,iterator_buf);
									if(SOCKET_ERROR==ret){
										m_LastWsaError=WSAGetLastError();
										delete buf;
										APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
									}
									sent+=ret;
								}
								break;
							}while(true);
						}
						delete buf;				
					}
					catch(SaplErrorDescription err)
					{
						m_LastWsaError=WSAGetLastError();
						LogDebugMessageIfDef(APL_T("MySend: Ошибка передачи буфера.");
						if(m_LastWsaError!=WSAENOBUFS){
							// пересылаем дальше
							APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
						}
						LogDebugMessageIfDef(APL_T("MySend: Уменьшаем размер передачи!");
						portion_size/=2;
						if(portion_size<MIN_PORTION_SIZE){
							// дальше уж дробить некуда. Совсем ошибка однако
							LogDebugMessageIfDef(APL_T("MySend: Размер передачи слишком мал!");
							APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
						}
						if(sent>0){
							// начать передачу по новой мы не могем - часть данных уже была отослана
							LogDebugMessageIfDef(APL_T("MySend: Часть данных уже была отослана!");
							APL_TRANSPORT_THROW(ASC_ERROR_IN_SOCKET);
						}
						continue;
					}
				}while(false);
				m_LastWsaError=0;
				LogDebugMessageIfDefFormat1("MySend: В результате размер порции %i",portion_size);
			}
		}
	}
	if(sent!=nBufLen1+nBufLen2+nBufLen3){
		LogDebugMessageIfDefFormat2("MySend: sent(%i)!=nBufLen1+nBufLen2+nBufLen3 (%i)",sent,nBufLen1+nBufLen2+nBufLen3);
		if(is_throw)
			APL_TRANSPORT_THROW(ASC_MISSED_SENT_SIZE);
	}
	* /
	return ret;
}

void CaplSocketClientE::ClearInternalData()
{

//#define __FUNCTION__ "CaplSocketClientE::ClearInternalData"
	
	LogDebugMessageIfDef(_T("ClearInternalData");
	if(m_InternalData!=0){
		delete m_InternalData;
		m_InternalData=0;
		m_size_InternalData=0;
		m_operation_in_progress=false;
		LeaveLogCriticalSection(&m_IsBlockedInternalBuf);
	}
}
/*
bool CaplSocketClientE::IsTimeOutDlg()
{

//#define __FUNCTION__ "CaplSocketClientE::IsTimeOutDlg"

	bool res;
	EnterLogCriticalSection(&m_ManageOperate);
	res=m_manage_mode==MANAGE_TIMEOUT;
	LeaveLogCriticalSection(&m_ManageOperate);
	return res;
}
* /
bool CaplSocketClientE::IsWaitDlg()
{

//#define __FUNCTION__ "CaplSocketClientE::IsWaitDlg"
	
	bool res;
	LogDebugMessageIfDef(_T("IsWaitDlg");
	EnterLogCriticalSection(&m_ManageOperate);
	res=m_manage_mode==MANAGE_WAITDLG;
	LogDebugMessageIfDef(res?"m_manage_mode==MANAGE_WAITDLG":"m_manage_mode!=MANAGE_WAITDLG");
	LeaveLogCriticalSection(&m_ManageOperate);
	return res;
}

bool CaplSocketClientE::IsActiveWaitDlg()
{

//#define __FUNCTION__ "CaplSocketClientE::IsActiveWaitDlg"
	
	bool res;
	LogDebugMessageIfDef(_T("IsActiveWaitDlg");
	EnterLogCriticalSection(&m_ManageOperate);
	res=m_wt_dlg!=0;
	LogDebugMessageIfDef(res?"m_wt_dlg!=0":"m_wt_dlg==0");
	LeaveLogCriticalSection(&m_ManageOperate);
	return res;
}

void CaplSocketClientE::SetManageMode(DWORD manage_mode)
{

//#define __FUNCTION__ "CaplSocketClientE::SetManageMode"
	
	LogDebugMessageIfDef(_T("SetManageMode");
	EnterLogCriticalSection(&m_ManageOperate);
	m_manage_mode=manage_mode;
	LogDebugMessageIfDef(m_manage_mode?"m_manage_mode==true":"m_manage_mode==false");
	LeaveLogCriticalSection(&m_ManageOperate);
}

bool CaplSocketClientE::IsBreak()
{

//#define __FUNCTION__ "CaplSocketClientE::IsBreak"
	
	bool res;
	LogDebugMessageIfDef(_T("IsBreak");
	EnterLogCriticalSection(&m_ManageOperate);
	res=m_flag_break;
	LogDebugMessageIfDef(m_flag_break?"m_flag_break==true":"m_flag_break==false");
	LeaveLogCriticalSection(&m_ManageOperate);
	return res;
}

void CaplSocketClientE::SetBreak(bool state)
{

//#define __FUNCTION__ "CaplSocketClientE::SetBreak"
	
	LogDebugMessageIfDef(_T("SetBreak");
	EnterLogCriticalSection(&m_ManageOperate);
	m_flag_break=state;
	LogDebugMessageIfDef(m_flag_break?"m_flag_break==true":"m_flag_break==false");
	LeaveLogCriticalSection(&m_ManageOperate);
	if(state)
		m_LastAscError=ASC_BREAK_CALL;
}

bool CaplSocketClientE::IsBufferFull()
{

//#define __FUNCTION__ "CaplSocketClientE::IsBufferFull"
	
	bool ret;
	LogDebugMessageIfDef(_T("IsBufferFull");
	EnterLogCriticalSection(&m_IsBlockedInternalBuf);
	ret=m_is_buffer_full;
	LogDebugMessageIfDef(m_is_buffer_full?"m_is_buffer_full==true":"m_is_buffer_full==false");
	LeaveLogCriticalSection(&m_IsBlockedInternalBuf);
	return ret;
}

void CaplSocketClientE::SetWaitDlgText(LPCTSTR waitdlg_text)
{

//#define __FUNCTION__ "CaplSocketClientE::SetWaitDlgText"
	
	m_waitdlg_text=waitdlg_text;
}


//#define __FUNCTION__ "CaplSocketClientE::"

CString CaplSocketClientE::GetDescriptionLastError()
{
	
	CString str;
	::GetDescriptionTransportError(m_LastAscError,m_LastWsaError,str);
	return str;
}

ASC_ERROR_CODES CaplSocketClientE::GetLastAscError(){
	return m_LastAscError;
}

int CaplSocketClientE::GetLastWsaError(){
	return m_LastWsaError;
}

void CaplSocketClientE::SetLastAscErrors(ASC_ERROR_CODES AscError){
	m_LastAscError=AscError;
//	m_LastWsaError=WSAError;
}

bool CaplSocketClientE::SetTimerParam(HWND timer_target,DWORD timer_id,DWORD timer_interval)
{

//#define __FUNCTION__ "CaplSocketClientE::SetTimerParam"
	
	m_LastAscError=ASC_NO_ERROR;
	if(timer_target==0 || timer_id==0 || timer_interval==0){
		m_LastAscError=ASC_MISSED_PARAM;
		return false;
	}
	m_timer_target=timer_target;
	m_timer_id=timer_id;
	m_timer_interval=timer_interval;
	return true;
}

bool CaplSocketClientE::SetTimeOut(DWORD timeout_call,DWORD timeout_my_receive)
{

//#define __FUNCTION__ "CaplSocketClientE::SetTimeOut"
	
	m_LastAscError=ASC_NO_ERROR;
// 	if(timeout_call<0){
// 		m_LastAscError=ASC_MISSED_PARAM;
// 		return false;
// 	}
	m_timeout_call=timeout_call;
	if(0==m_timeout_call)
	{
		m_manage_mode=MANAGE_ABSENT;
		m_timeout_call=1000*60*60*24*7;
	}
	m_timeout_my_receive=timeout_my_receive<=0?50000:timeout_my_receive;
	return true;
}

bool CaplSocketClientE::IsReadyData()
{

//#define __FUNCTION__ "CaplSocketClientE::IsReadyData"
/*
	if(IOCtl(FIONREAD, &m_LastReadyData)){
		return (m_LastReadyData!=0);
	}
	m_LastWsaError=WSAGetLastError();

	LogDebugMessageIfDefFormat1(" IsReadyData - Ошибка (%i) определения готовности данных",m_LastWsaError);
	m_LastReadyData=0;
* /
	return false;
}


//#define __FUNCTION__ "CaplSocketClientE::"

void CaplSocketClientE::SetRenewFunction(AFX_THREADPROC renew_function,LPVOID parameter_renew_function)
{
	m_renew_function=renew_function;
	m_parameter_renew_function=parameter_renew_function;
}

bool CaplSocketClientE::GetHostName(CString &name)
{

//#define __FUNCTION__ "CaplSocketClientE::GetHostName"
	
	bool ret=true;
	name="";
	char* buf=new char[1024];
	if(gethostname(buf,1024)==SOCKET_ERROR){
		m_LastAscError=ASC_ERROR_IN_SOCKET;
		m_LastWsaError=WSAGetLastError();
		ret=false;
	}
	name=buf;
	delete buf;
	return ret;
}

long CaplSocketClientE::GetCompIp()
{

//#define __FUNCTION__ "CaplSocketClientE::GetCompIp"
	
	long id=0;
	char name[256];
	int res=gethostname (name,256);
	SOCKADDR_IN contact_sin;
	PHOSTENT phe =gethostbyname(name);
	//Копируем адрес узла
	memcpy((char FAR *)&(contact_sin.sin_addr),phe->h_addr,phe->h_length);
	memcpy(&id,&contact_sin.sin_addr,4);
	//  CString str;
	//	str=inet_ntoa(contact_sin.sin_addr);
	return id;
}

*/