www.pudn.com > server_client.rar > Logging_Handler.h, change:2007-10-18,size:7354b


/* 
** Logging_Handler.h,v 1.4 2001/10/15 18:35:44 shuston Exp 
** 
** Copyright 2001 Addison Wesley. All Rights Reserved. 
*/ 
 
#ifndef _LOGGING_HANDLER_H 
#define _LOGGING_HANDLER_H 
 
#include "ace/ACE.h" 
#include "ace/CDR_Stream.h" 
#include "ace/FILE_IO.h" 
#include "ace/INET_Addr.h" 
#include "ace/Message_Block.h" 
#include "ace/os_include/os_netdb.h" 
#include "ace/SOCK_Connector.h" 
#include "ace/Synch.h"  
#include "ace/streams.h" 
#include "ace/SOCK_Stream.h" 
#include "ace/Thread.h" 
 
static ACE_Thread_Mutex thread_mutex; 
 
#define MAX_NAME_LENGTH 255 
 
class ACE_Message_Block; 
 
class Logging_Handler 
{ 
protected: 
  ACE_FILE_IO &log_file_; // Reference to a log file. 
  ACE_SOCK_Stream logging_peer_; // Connected to the client. 
 
public: 
 
  // Initialization and termination methods. 
  Logging_Handler (ACE_FILE_IO &log_file): log_file_ (log_file) {} 
  Logging_Handler (ACE_FILE_IO &log_file, 
                   ACE_HANDLE handle): log_file_ (log_file) 
  { logging_peer_.set_handle (handle); } 
  Logging_Handler (ACE_FILE_IO &log_file, 
                   const ACE_SOCK_Stream &logging_peer) 
    : log_file_ (log_file), logging_peer_ (logging_peer) {} 
  int close () { return logging_peer_.close (); } 
 
  // Receive one log record from a connected client.   Returns 
  // length of record on success and <mblk> contains the 
  // hostname, <mblk->cont()> contains the log record header 
  // (the byte order and the length) and the data.  Returns -1 on 
  // failure or connection close. 
 
int Logging_Handler::recv_log_record (ACE_Message_Block *&mblk) 
{ 
  //使用块链表保存收到信息 
  ACE_INET_Addr peer_addr; 
  logging_peer_.get_remote_addr (peer_addr); 
  mblk = new ACE_Message_Block (MAXHOSTNAMELEN + 1); 
  peer_addr.get_host_name (mblk->wr_ptr (), MAXHOSTNAMELEN); 
  mblk->wr_ptr (strlen (mblk->wr_ptr ()) + 1); // Go past name 
  // Allocate a message block for the payload; initially at least 
  // large enough to hold the header, but needs some room for 
  // alignment. 
  ACE_Message_Block *payload = 
    new ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE); 
  // Align the Message Block for a CDR stream 
  ACE_CDR::mb_align (payload); 
  if (logging_peer_.recv_n (payload->wr_ptr (), 8) == 8) { 
    payload->wr_ptr (8);               // Reflect addition of 8 bytes 
 
    // Create a CDR stream to parse the 8-byte header. 
    ACE_InputCDR cdr (payload); 
 
    // Extract the byte-order and use helper methods to 
    // disambiguate octet, booleans, and chars. 
    ACE_CDR::Boolean byte_order; 
    cdr >> ACE_InputCDR::to_boolean (byte_order); 
 
    // Set the byte-order on the stream... 
    cdr.reset_byte_order (byte_order); 
 
    // Extract the length 
    ACE_CDR::ULong length; 
    cdr >> length; 
 
    // Ensure there's sufficient room for log record payload. 
    ACE_CDR::grow (payload, 8 + ACE_CDR::MAX_ALIGNMENT + length); 
 
    // Use <recv_n> to obtain the contents. 
    if (logging_peer_.recv_n (payload->wr_ptr (), length) > 0) { 
      payload->wr_ptr (length);   // Reflect additional bytes 
      // Chain the payload to mblk via the contination field. 
      mblk->cont (payload); 
	   
	  return length;	 
    } 
  } 
  // Error cases end up here, so we need to release the memory to 
  // prevent a leak. 
  payload->release (); 
  payload = 0; 
  mblk->release (); 
  mblk = 0; 
  return -1; 
} 
 
 
 
  // Write one record to the log file.  The <mblk> contains the 
  // hostname and the <mblk->cont> contains the log record. 
  // Returns length of record written on success, or -1 on failure. 
 
int Logging_Handler::write_log_record (ACE_Message_Block *mblk) 
{ 
  CString m_Msg; 
  CServerDlg *dlg=(CServerDlg*)AfxGetApp()->GetMainWnd(); 
  char* peer_host; 
  peer_host=mblk->rd_ptr(); 
  char* user_recv; 
  ACE_FILE_Connector connector; 
   
  // Peer hostname is in the <mblk> and the log record data 
  // is in its continuation. 
  if(mblk->cont()->length()>MAX_NAME_LENGTH+8)//如果是文件,长度一定大于文件名长度+8 
  { 
    user_recv=mblk->cont()->rd_ptr()+8; 
	if (dlg->MessageBox("是否接收数据?","提示",MB_YESNO)==IDYES) 
	{	 
			BROWSEINFO bInfo; 
			bInfo.hwndOwner = dlg->m_hWnd; 
			bInfo.pidlRoot  = NULL; 
			char filename[MAX_PATH]; 
			char dir[MAX_PATH]; 
			memset(filename,0,MAX_PATH); 
			memset(dir,0,MAX_PATH); 
			 
			bInfo.pszDisplayName = filename; 
			bInfo.lpszTitle ="请选择目的路径"; 
			bInfo.ulFlags = BIF_BROWSEINCLUDEFILES|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS|BIF_BROWSEFORCOMPUTER; 
			bInfo.lParam  =NULL; 
			bInfo.lpfn  =NULL; 
			bInfo.iImage = 0; 
 
			LPITEMIDLIST lpList =  SHBrowseForFolder(&bInfo); 
			SHGetPathFromIDList(lpList,dir); 
		 
		CString save_path=dir; 
		save_path+="\\"; 
		CString file_name=user_recv; 
		connector.connect (log_file_, 
							ACE_FILE_Addr (save_path+user_recv), 
                            0, // No timeout. 
                            ACE_Addr::sap_any, // Ignored. 
                            0, // Don't try to reuse the addr. 
                            O_RDWR|O_CREAT|O_APPEND, 
                            ACE_DEFAULT_FILE_PERMS); 
	} 
  	if (log_file_.send_n(mblk->cont()->rd_ptr()+MAX_NAME_LENGTH+8,mblk->cont()->length()-MAX_NAME_LENGTH-8)==-1) 
	{ 
		LocalFree(peer_host); 
		LocalFree(user_recv); 
  		return -1; 
	}//写入文件tmp 
	dlg->MessageBox("接收完毕!"); 
  } 
  else//如果是文字信息 
  { 
    user_recv=mblk->cont()->rd_ptr()+8; 
	user_recv[mblk->cont()->length()-8]='\0';//结束字符串 
	if((user_recv[0]=='!'||user_recv[0]=='!')&&user_recv[1]=='\0') 
	{	 
		LocalFree(peer_host); 
		LocalFree(user_recv); 
		dlg->MessageBox("对方已退出!"); 
		return -1; 
	} 
    connector.connect (log_file_, 
							ACE_FILE_Addr ("message.log"), 
                            0, // No timeout. 
                            ACE_Addr::sap_any, // Ignored. 
                            0, // Don't try to reuse the addr. 
                            O_RDWR|O_CREAT|O_APPEND, 
                            ACE_DEFAULT_FILE_PERMS); 
	if (log_file_.send_n(peer_host,strlen(peer_host))==-1) 
	{ 
		LocalFree(peer_host); 
		LocalFree(user_recv); 
  		return -1; 
	}//写入文件tmp 
	if (log_file_.send_n(":",1)==-1) 
	{ 
		LocalFree(peer_host); 
		LocalFree(user_recv); 
  		return -1; 
	}//写入文件tmp 
	if (log_file_.send_n(mblk->cont()->rd_ptr()+8,mblk->cont()->length()-8)==-1) 
	{ 
		LocalFree(peer_host); 
		LocalFree(user_recv); 
  		return -1; 
	}//写入文件tmp 
	if (log_file_.send_n("  ",1)==-1) 
	{ 
		LocalFree(peer_host); 
		LocalFree(user_recv); 
  		return -1; 
	}//写入文件tmp 
  } 
   
  m_Msg.Format("From %s : %s",peer_host,user_recv);				 
  thread_mutex.acquire(); 
  dlg->m_cMsg.AddString(m_Msg); 
  thread_mutex.release(); 
  LocalFree(peer_host); 
  LocalFree(user_recv); 
 
  return mblk->total_length (); 
} 
 
  // Log one record by calling <recv_log_record> and 
  // <write_log_record>.  Returns 0 on success and -1 on failure. 
int Logging_Handler::log_record () 
{ 
  ACE_Message_Block *mblk = 0; 
  if (recv_log_record (mblk) == -1) 
    return -1; 
  else { 
    int result = write_log_record (mblk); 
    mblk->release (); // Free up the contents. 
    log_file_.close (); 
    return result == -1 ? -1 : 0; 
  } 
} 
	 
  // Accessor method. 
  ACE_SOCK_Stream &peer () { return logging_peer_; } 
}; 
 
#endif /* _LOGGING_HANDLER_H */