简化asio的聊天代码 去除ROOM的设计
所有连接客户端均在同一个ROOM下
chat message 使用boost自带示例的头文件
#pragma once #include <cstdio> #include <cstdlib> #include <cstring> class chat_message { public: enum { header_length = 4 }; enum { max_body_length = 512 }; chat_message(): body_length_(0) {} const char* data()const { return data_; } char* data() { return data_; } size_t length()const { return header_length + body_length_; } const char* body()const { return data_ + header_length; } char* body() { return data_ + header_length; } size_t body_length()const { return body_length_; } void body_length(size_t new_length) { body_length_ = new_length; if (body_length_ > max_body_length) body_length_ = max_body_length; } bool decode_header() { using namespace std; 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 encode_header() { using namespace std; char header[header_length + 1] = ""; sprintf(header,"%4d",static_cast<int>(body_length_)); memcpy(data_,header,header_length); } private: char data_[header_length + max_body_length]; size_t body_length_; };
// MyChat.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/asio.hpp> #include <set> #include <iostream> #include "chat_message.h" using namespace boost::asio::ip; const int defaultPort = 8899; class chat_session; typedef boost::shared_ptr<chat_session> chat_session_ptr; class chat_session : public boost::enable_shared_from_this<chat_session> { public: chat_session(boost::asio::io_service& io_service, std::set<chat_session_ptr>& sessionList) : socket_(io_service), sessionList_(sessionList) { } ~chat_session() { std::cout << "~chat_session()" << std::endl; } tcp::socket& socket() { return socket_; } void start() { sessionList_.insert(shared_from_this()); boost::asio::async_read(socket_, boost::asio::buffer(read_msg_.data(), chat_message::header_length), boost::bind( &chat_session::handle_read_header, shared_from_this(), boost::asio::placeholders::error)); } void handle_read_header(const boost::system::error_code& error) { if (!error && read_msg_.decode_header() ) { boost::asio::async_read(socket_, boost::asio::buffer(read_msg_.body(), read_msg_.body_length()), boost::bind(&chat_session::handle_read_body, shared_from_this(), boost::asio::placeholders::error)); } else { // occur error,delete from list sessionList_.erase(shared_from_this()); socket_.shutdown(tcp::socket::shutdown_both); socket_.close(); return; } } void handle_read_body(const boost::system::error_code& error) { if (!error) { std::cout << read_msg_.data() << std::endl; boost::asio::async_read(socket_, boost::asio::buffer(read_msg_.data(), chat_message::header_length), boost::bind(&chat_session::handle_read_header, shared_from_this(), boost::asio::placeholders::error)); } else { // occur error,delete from list sessionList_.erase(shared_from_this()); socket_.shutdown(tcp::socket::shutdown_both); socket_.close(); return; } } private: char recvbuf[5]; tcp::socket socket_; chat_message read_msg_; std::set<chat_session_ptr>& sessionList_; }; typedef boost::shared_ptr<chat_session> chat_session_ptr; class chat_server { public: chat_server(boost::asio::io_service& io_service, const tcp::endpoint& endpoint) : io_service_(io_service), acceptor_(io_service, endpoint) { start_accept(); } void start_accept() { chat_session_ptr new_session(new chat_session(io_service_, sessionList_)); acceptor_.async_accept(new_session->socket(), boost::bind(&chat_server::handle_accept, this, new_session, boost::asio::placeholders::error)); } void handle_accept(chat_session_ptr session, const boost::system::error_code& error) { if (!error) { session->start(); } start_accept(); } private: boost::asio::io_service& io_service_; tcp::acceptor acceptor_; std::set<chat_session_ptr> sessionList_; }; typedef boost::shared_ptr<chat_server> chat_server_ptr; int main() { boost::asio::io_service io_service; tcp::endpoint endpoint(tcp::v4(), defaultPort); chat_server chatServer(io_service, endpoint); io_service.run(); return 0; }
时间: 2024-10-10 21:50:04