go服务器与mfc做客户端的简单群聊Demo

//先前代码对中文处理有问题,以下代码做了修正,

//go语言服务器代码

package main

import(
	"fmt"
	"net"
	"strconv"
	"runtime" //go线程库
    "strings"
)

var conns map[string]net.Conn

////////////////////////////////////////////////////////
//
//错误检查
//
////////////////////////////////////////////////////////
func checkError(err error,info string) (res bool) {
	
	if(err != nil){
		fmt.Println(info+"  " + err.Error())
		//checkOnlineUser()
		return false
	}
	return true
}

////////////////////////////////////////////////////////
//
//服务器端接收数据线程
//参数:
//		数据连接 conn
//		通讯通道 messages
//
////////////////////////////////////////////////////////
func Handler(conn net.Conn,messages chan string){
	
	//fmt.Println("connection is connected from ...",conn.RemoteAddr().String())
	
	buf := make([]byte,1024)

	for{
		lenght, err := conn.Read(buf)
		if(checkError(err,"Connection")==false){
			delete(conns,conn.RemoteAddr().String())
			conn.Close()
			checkOnlineUser()
			break
		}
		if lenght > 0{
			buf[lenght]=0
		}

        fmt.Println("Rec[",conn.RemoteAddr().String(),"] Say :" ,buf[:lenght])
	
		say := conn.RemoteAddr().String() + " say: ";
		s := []byte(say)
   
		name := buf[8:lenght]
	
		id := buf[4:8]
		
        shead := buf[0:4]
        sh := string(shead[:])
        sh = strings.Replace(sh, " ", "", -1)  
		i2,_ := strconv.Atoi(sh)
		i2 = i2 + len(say)
       
        slen := strconv.Itoa(i2) 
      
        sl := fmt.Sprintf("%4s",slen)
        head := []byte(sl)
		
		content := make([]byte,2048)

		for i := 0; i < len(head); i++{
			content[i] = head[i]
		}
		
		j := 0
		for i:= len(head); i < len(id) + len(head) ; i++{
			 content[i] = id[j]
			 j++
		}
		j=0
		for i:=len(head)+len(id); i < len(s) + len(head) + len(id) ; i++{
			content[i] = s[j]
			 j++
		}
		j = 0
		for i:=len(head)+len(id)+len(s); i < len(s) + len(head) + len(id) + len(name); i++{
			content[i] = name[j]
			 j++
		}
	    sum := len(s) + len(head) + len(id) + len(name)
		reciveStr := string(content[:sum])
		
       
		messages <- reciveStr
			
	}
		
}


//////////////////////
//
//检测在线用户
//
//////////////////////

func checkOnlineUser(){

   
    var msg string
    var slen string
  
    //for{

    	for key,_ := range conns {
			
			//fmt.Println("connection is connected from ...",key)
			msg += key;
     		msg += "-";
			
		}
	    l1:=len([]rune(msg)) 
	    if l1==0{
	    	return
	    }
		msg = string(msg[0:l1-1])
		

        slen = strconv.Itoa(l1-1) 
        //fmt.Println(slen)
        sl := fmt.Sprintf("%4s",slen)
       // fmt.Println(sl)
        stype := "1000"
        msg = sl + stype + msg
		for _,value := range conns {
			
			//fmt.Println("发送内容",msg)
			 runtime.Gosched();
			_,err :=value.Write([]byte(msg))
			
			 if(err != nil){
				fmt.Println(err.Error(),"checkOnlineUser")
				//delete(conns,key)
			}else{
				fmt.Println("发送用户列表了")
			}
			
			
		}
	 
   // }
	
	

}
////////////////////////////////////////////////////////
//
//服务器发送数据的线程
//
//参数
//		连接字典 conns
//		数据通道 messages
//
////////////////////////////////////////////////////////
func echoHandler(conns *map[string]net.Conn,messages chan string){
	
	
	for{
		msg:= <- messages

		for _,value := range *conns {
			
			//fmt.Println("connection is connected from ...",key)
			_,err :=value.Write([]byte(msg))
			if(err != nil){
				fmt.Println(err.Error(),"123")
				//delete(*conns,key)
			}
			
			
		}
	}
	
}


////////////////////////////////////////////////////////
//
//启动服务器
//参数
//	端口 port
//
////////////////////////////////////////////////////////
func StartServer(port string){
		service:=":"+port //strconv.Itoa(port);
		tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
		checkError(err,"ResolveTCPAddr")
		l,err := net.ListenTCP("tcp",tcpAddr)
		checkError(err,"ListenTCP")
		//conns=make(map[string]net.Conn)
		messages := make(chan string)
		//imsgstart = 1
		//启动服务器广播线程
		go echoHandler(&conns,messages)
		
		for  {
			fmt.Println("msg  Listening ...")
			conn,err := l.Accept()
			checkError(err,"Accept")
			fmt.Println("Accepting ...")
			conns[conn.RemoteAddr().String()]=conn
			//fmt.Println(conn.RemoteAddr().String())
			 checkOnlineUser()
			//启动一个新线程
			go Handler(conn,messages) 
			
		}
		
}

func main(){

    conns=make(map[string]net.Conn)
   
	go StartServer("7777");
	fmt.Println("服务启动完成")
	for{

	}
	
}


//mfc客户端主要代码
// qunliaoDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "qunliao.h"
#include "qunliaoDlg.h"
#include <atlbase.h>
#include <boost/format.hpp>     
#include <boost/tokenizer.hpp>     
#include <boost/algorithm/string.hpp>   
#include < boost/locale/encoding.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>   
#define BOOST_DATE_TIME_SOURCE   

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CqunliaoDlg 对话框




CqunliaoDlg::CqunliaoDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CqunliaoDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CqunliaoDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST3, m_ListCtrl);
	DDX_Control(pDX, IDC_EDIT2, m_EditSendText);
	DDX_Control(pDX, IDC_LIST1, m_ListMsg);
}

BEGIN_MESSAGE_MAP(CqunliaoDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_BUTTON1, &CqunliaoDlg::OnBnClickedButton1)

	ON_WM_CLOSE()
	ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST3, &CqunliaoDlg::OnNMCustomdrawList3)
	ON_BN_CLICKED(IDC_BUTTON2, &CqunliaoDlg::OnBnClickedButton2)
END_MESSAGE_MAP()

void CqunliaoDlg::init()
{
  	
    tcp::resolver resolver(io_service);
    tcp::resolver::query query("127.0.0.1", "7777");
    tcp::resolver::iterator iterator = resolver.resolve(query);

	tcp::resolver resolver2(io_service_user);
    tcp::resolver::query query2("127.0.0.1", "8888");
    tcp::resolver::iterator iterator2 = resolver2.resolve(query2);

	buser = true;
	bmsg = true;
	m_pclient = boost::shared_ptr<chat_client>(new chat_client(io_service, iterator));
	//m_puserclient = boost::shared_ptr<chat_client_user>(new chat_client_user(io_service, iterator2));
	//m_pusername = boost::shared_ptr<chat_client>(new chat_client(io_service, iterator));
	m_pthread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service)));
	//m_pthread2 = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&boost::asio::io_service::run, &io_service_user)));
	m_pmsgthread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CqunliaoDlg::GetMessage,this)));
	//m_puserthread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CqunliaoDlg::GetUserList,this)));
	//m_pusernamethread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CqunliaoDlg::GetUserName,this)));
	//m_pthread->detach();
	//m_pmsgthread->detach();
}
// CqunliaoDlg 消息处理程序

BOOL CqunliaoDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	m_ListMsg.DeleteAllItems();
	m_ListMsg.InsertColumn(0, _T(""));
    m_ListMsg.SetColumnWidth(0, 200);//设置列宽  
	m_ListCtrl.DeleteAllItems();
	m_ListCtrl.InsertColumn(0, _T(""));
    m_ListCtrl.SetColumnWidth(0, 160);//设置列宽  
    init();
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CqunliaoDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CqunliaoDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CqunliaoDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}
//void CqunliaoDlg::GetUserName()
//{
//	while(true){
//		if(m_puserclient->GetChatMessage().body_length()){
//			m_strUserName =  m_puserclient->GetChatMessage().body();
//			m_puserclient->GetChatMessage().clear();
//			break;
//		}else{
//		   boost::this_thread::sleep(boost::posix_time::seconds(1));  
//		}
//	}
//	m_puserthread = boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&CqunliaoDlg::GetUserList,this)));
//}
void CqunliaoDlg::GetUserMsg()
{
	        std::string strTime = boost::posix_time::to_iso_string(  
            boost::posix_time::second_clock::local_time());  
  
            // 这时候strTime里存放时间的格式是YYYYMMDDTHHMMSS,日期和时间用大写字母T隔开了   
  
            int pos = strTime.find('T');  
            strTime.replace(pos,1,std::string(" "));  
            strTime.replace(pos + 3,0,std::string(":"));  
            strTime.replace(pos + 6,0,std::string(":"));  
			strTime.replace(0+4,0,std::string("-"));
			strTime.replace(0+4+3,0,std::string("-"));
			//std::string str2();
			std::wstring wStr = boost::locale::conv::utf_to_utf<wchar_t>( m_pclient->GetChatMessage().body() );
			CString str(wStr.c_str());
			CString strtime(strTime.c_str());
			int i = m_ListMsg.GetItemCount();
			CString col;
			col.Format(_T("%d"),i);
			m_ListMsg.InsertItem(i,col);
			m_ListMsg.SetItemText(i,0,strtime);
			col.Format(_T("%d"),i+1);
			m_ListMsg.InsertItem(i+1,col);
			//str = m_strUserName + "说:" + str;
			
			m_ListMsg.SetItemText(i+1,0,str);
			m_pclient->GetChatMessage().clear();

}
void CqunliaoDlg::GetUserList()
{
  

		{
			//CString str();
	
		    std::vector<std::string> vecSegTag;    
            // boost::is_any_of这里相当于分割规则了     
			std::string str = m_pclient->GetChatMessage().body();
            boost::split(vecSegTag, str ,boost::is_any_of(_T("-")));  
			m_ListCtrl.DeleteAllItems();
		
			CString col, strname;
			//std::string tmp;
			for(int i = 0; i < vecSegTag.size(); i++){
			  
			     col.Format(_T("%d"),i);
			     m_ListCtrl.InsertItem(i,col);
				 CString strname(vecSegTag[i].c_str());
				 m_ListCtrl.SetItemText(i,0,strname);
			}
			/*int i = m_ListCtrl.GetItemCount();
			CString col;
			col.Format(_T("%d"),i);
			m_ListCtrl.InsertItem(i,col);
			m_ListCtrl.SetItemText(i,0,str);*/
			m_pclient->GetChatMessage().clear();
		}
		
}
void CqunliaoDlg::GetMessage()
{
	while(bmsg){
		try{
		if(m_pclient->GetChatMessage().body_length())
		{
			std::string msgtype = m_pclient->GetChatMessage().type();
			if(msgtype=="1000")//用户列表
			{
				GetUserList();
			}else{
			   GetUserMsg();
			}
		}else{
		   boost::this_thread::sleep(boost::posix_time::seconds(1));  
		}
		}catch(std::exception e){
		
			return;
		}catch(...){
		
			return;
		}
	}
}
void CqunliaoDlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	  using namespace std; // For strlen and memcpy.
	  USES_CONVERSION;
      chat_message msg;
	  CString str;
	  m_EditSendText.GetWindowText(str);
	  if(str.IsEmpty()) {
	     return;
	  }
	 // char *chr=T2A(str);
	  //char *chr = "我";
	  std::wstring wstr = str.GetString();
	  string test2=boost::locale::conv::from_utf(wstr,"UTF-8");
      //WideCharToMultiByte(CP_ACP,0,str.GetBuffer(),-1,chr,str.GetLength(),NULL,NULL);
	  msg.body_length(test2.length());
	  memcpy(msg.body(), test2.c_str(), msg.body_length());
      msg.encode_header();
	  msg.msg_type("1001");
      m_pclient->write(msg);
	  //delete chr;
	 // chr = NULL;
}


void CqunliaoDlg::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_pthread->interrupt();
	//m_pthread2->interrupt();
	m_pclient->close();
	//m_puserclient->close();
	//m_pthread->join();
	buser=false;
	bmsg=false;
    m_pmsgthread->join();
  //  m_puserthread->join();
    //m_pthread->interrupt();
	m_pmsgthread->interrupt();
	//m_puserthread->interrupt();
	CDialog::OnClose();
}

void CqunliaoDlg::OnNMCustomdrawList3(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
}


boost的asio代码

//
// chat_client.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include <cstdlib>
#include <deque>
#include <iostream>
#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>  
#include "chat_message.hpp"

using namespace boost::asio;
using boost::asio::ip::tcp;

typedef std::deque<chat_message> chat_message_queue;

class chat_client
{
public:
  chat_client(boost::asio::io_service& io_service,
      tcp::resolver::iterator endpoint_iterator)
    : io_service_(io_service),
      socket_(io_service)
  {
	data_.assign('\0');
    //tcp::endpoint endpoint = *endpoint_iterator;
	tcp::endpoint endpoint(ip::address_v4::from_string("127.0.0.1"), 7777);
    socket_.async_connect(endpoint,
        boost::bind(&chat_client::handle_connect, this,
          boost::asio::placeholders::error, ++endpoint_iterator));
  }

  void write(const chat_message& msg)
  {
    io_service_.post(boost::bind(&chat_client::do_write, this, msg));
  }

  //void write(const std::string& user){
  //  io_service_.post(boost::bind(&chat_client::do_write, this, user));
  //}
  void close()
  {
    io_service_.post(boost::bind(&chat_client::do_close, this));
  }
  public:
	  chat_message& GetChatMessage(){
  
	  return read_msg_;
  }
private:

  void handle_connect(const boost::system::error_code& error,
      tcp::resolver::iterator endpoint_iterator)
  {
    if (!error)
    {
      boost::asio::async_read(socket_,
          boost::asio::buffer(read_msg_.data(), chat_message::header_length),
          boost::bind(&chat_client::handle_read_header, this,
            boost::asio::placeholders::error));
    }
    /*else if (endpoint_iterator != tcp::resolver::iterator())
    {
      socket_.close();
      tcp::endpoint endpoint = *endpoint_iterator;
      socket_.async_connect(endpoint,
          boost::bind(&chat_client::handle_connect, this,
            boost::asio::placeholders::error, ++endpoint_iterator));
    }*/
  }

  void handle_read_header(const boost::system::error_code& error)
  {
	 /* if(!error &&strcmp(read_msg_.data(),"user")==0){
		
		 boost::asio::async_read(socket_,
			 boost::asio::buffer(read_msg_.user(), 1024),
          boost::bind(&chat_client::handle_read_userlist, this,
            boost::asio::placeholders::error));
	  }
    else */if (!error && read_msg_.decode_header())
    {
      boost::asio::async_read(socket_,
          boost::asio::buffer(read_msg_.msg_type(), chat_message::msg_type_length),
          boost::bind(&chat_client::handle_read_msg_type, this,
            boost::asio::placeholders::error));
    }
    else
    {
      do_close();
    }
  }

   void handle_read_msg_type(const boost::system::error_code& error)
  {
    if (!error)
    {
		std::cout.write(read_msg_.msg_type(), chat_message::msg_type_length);
      std::cout << "\n";
      boost::asio::async_read(socket_,
		  boost::asio::buffer(read_msg_.body(), read_msg_.body_length()),
          boost::bind(&chat_client::handle_read_body, this,
            boost::asio::placeholders::error));
    }
    else
    {
      do_close();
    }
  }

  void handle_read_body(const boost::system::error_code& error)
  {
    if (!error)
    {
      std::cout.write(read_msg_.body(), read_msg_.body_length());
      std::cout << "\n";
      boost::asio::async_read(socket_,
          boost::asio::buffer(read_msg_.data(), chat_message::header_length),
          boost::bind(&chat_client::handle_read_header, this,
            boost::asio::placeholders::error));
    }
    else
    {
      do_close();
    }
  }
  void handle_read_userlist(const boost::system::error_code& error)
  {
    if (!error)
    {
      /*std::cout.write(read_msg_.body(), read_msg_.body_length());
      std::cout << "\n";*/
	  m_userlist.append(data_.data());
	  data_.assign('\0');
      boost::asio::async_read(socket_,
          boost::asio::buffer(data_),
          boost::bind(&chat_client::handle_read_userlist, this,
            boost::asio::placeholders::error));
    }
    else
    {
      do_close();
    }
  }

  void do_write(chat_message msg)
  {
    bool write_in_progress = !write_msgs_.empty();
    write_msgs_.push_back(msg);
    if (!write_in_progress)
    {
      boost::asio::async_write(socket_,
          boost::asio::buffer(write_msgs_.front().data(),
            write_msgs_.front().length()),
          boost::bind(&chat_client::handle_write, this,
            boost::asio::placeholders::error));
    }
  }

  //void do_write(std::string& user)
  //{
  // 
  //  {
  //    boost::asio::async_write(socket_,
  //        boost::asio::buffer(user,
  //          user.length()),
  //        boost::bind(&chat_client::handle_write, this,
  //          boost::asio::placeholders::error));
  //  }
  //}
  void handle_write(const boost::system::error_code& error)
  {
    if (!error)
    {
      write_msgs_.pop_front();
      if (!write_msgs_.empty())
      {
        boost::asio::async_write(socket_,
            boost::asio::buffer(write_msgs_.front().data(),
              write_msgs_.front().length()),
            boost::bind(&chat_client::handle_write, this,
              boost::asio::placeholders::error));
      }
    }
    else
    {
      do_close();
    }
  }

  void do_close()
  {
    socket_.close();
  }

private:
  boost::asio::io_service& io_service_;
  tcp::socket socket_;
  chat_message read_msg_;
  chat_message_queue write_msgs_;
  std::string m_userlist;
  boost::array<char, 1024> data_;
};

//int main(int argc, char* argv[])
//{
//  try
//  {
//  /*  if (argc != 3)
//    {
//      std::cerr << "Usage: chat_client <host> <port>\n";
//      return 1;
//    }*/
//
//    boost::asio::io_service io_service;
//   // boost::asio::ip::tcp::socket socket(io_service); 
//	std::string ip = boost::asio::ip::address().to_string();
//    tcp::resolver resolver(io_service);
//    tcp::resolver::query query("127.0.0.1", "7777");
//    tcp::resolver::iterator iterator = resolver.resolve(query);
//
//	//tcp::resolver::iterator end; // End marker.  
// //   while (iterator != end)  
// //   {  
// //       tcp::endpoint ep = *iterator++;  
// //       std::cout << ep.address().to_string() << std::endl;  
//	//	std::cout << ep.port() << std::endl;
// //   }  
//   // getchar();
//    chat_client c(io_service, iterator);
//
//    boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
//
//    char line[chat_message::max_body_length + 1];
//    while (std::cin.getline(line, chat_message::max_body_length + 1))
//    {
//      using namespace std; // For strlen and memcpy.
//      chat_message msg;
//      msg.body_length(strlen(line));
//      memcpy(msg.body(), line, msg.body_length());
//      msg.encode_header();
//      c.write(msg);
//    }
//
//    c.close();
//    t.join(); 
//  }
//  catch (std::exception& e)
//  {
//    std::cerr << "Exception: " << e.what() << "\n";
//  }
//
//  return 0;
//}

//
// chat_message.hpp
// ~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//


#ifndef CHAT_MESSAGE_HPP
#define CHAT_MESSAGE_HPP


#include <cstdio>
#include <cstdlib>
#include <cstring>


class chat_message
{
public:
  enum { header_length = 4 };
  enum { max_body_length = 2048 };
  enum { msg_type_length = 4 };


  chat_message()
    : body_length_(0)
  {
 memset(data_,0,header_length + msg_type_length + max_body_length);
 memset(msg_type_,0,msg_type_length+1);
  }


  const char* data() const
  {
    return data_;
  }


  char* data()
  {
    return data_;
  }


  void clear()
  {
     memset(data_,0,header_length + msg_type_length + max_body_length);
memset(msg_type_,0,msg_type_length+1);
     body_length_ = 0;
  }


  size_t length() const
  {
    return header_length + msg_type_length + body_length_;
  }


  const char* body() const
  {
    return data_ + header_length + msg_type_length ;
  }


  char * msg_type(){
  
 return data_ + header_length;
  }
  const char* type(){


      strncat(msg_type_, data_+header_length,msg_type_length );
 return msg_type_;
  }
  char* body()
  {
    return data_ + header_length+ msg_type_length ;
  }
  char* user(){
     return data_ + header_length+ msg_type_length ;
  }
  size_t body_length() const
  {
    return body_length_;
  }


  void body_length(size_t length)
  {
    body_length_ = length;
    if (body_length_ > max_body_length)
      body_length_ = max_body_length;
  }


  bool decode_header()
  {
    using namespace std; // For strncat and atoi.
    char header[header_length + 1] = "";
    strncat(header, data_, header_length);
    body_length_ = atoi(header);
    if (body_length_ > max_body_length)
    {
      body_length_ = 0;
      return false;
    }
    return true;
  }


  void msg_type(std::string stype)
  {
 memcpy(data_+header_length,stype.c_str(), msg_type_length);
  }


  void encode_header()
  {
    using namespace std; // For sprintf and memcpy.
    char header[header_length + 1] = "";
    sprintf(header, "%4d", body_length_);
    memcpy(data_, header, header_length);
  }


private:
  char data_[header_length + msg_type_length + max_body_length];
  char msg_type_[msg_type_length+1];
  size_t body_length_;
};


#endif // CHAT_MESSAGE_HPP

猜你喜欢

转载自blog.csdn.net/abqchina/article/details/54286871
今日推荐