使用muduo编写聊天室
来源:互联网 发布:淘宝塑唐玩具是正品吗 编辑:程序博客网 时间:2024/06/07 03:05
服务端,我们需要设计的回调函数有:连接的建立与断开,消息到来。
消息分包的话,这里采用的头部设置长度信息。
#include <muduo_five\net\EventLoop.h>#include <muduo_five\net\TcpServer.h>#include <string>#include <set>#include <iostream>using namespace std;class ChatServer : noncopyable{public: ChatServer(EventLoop* loop, const InetAddress& listenAddr) : server_(loop, listenAddr, "ChatServer") { server_.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1)); server_.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3)); } void start() { server_.start(); }private: void onConnection(const TcpConnectionPtr& conn) { if (conn->connected()) { connections_.insert(conn); } else { connections_.erase(conn); } } void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime) { while (buf->readableBytes() >= kHeaderLen) { const void* data = buf->peek(); int32_t be32 = *static_cast<const int32_t*>(data); // SIGBUS const int32_t len = ntohl(be32); if (len > 65536 || len < 0) { conn->shutdown(); break; } else if (buf->readableBytes() >= len + kHeaderLen) { buf->retrieve(kHeaderLen); string message(buf->peek(), len); onStringMessage(conn, message, receiveTime); buf->retrieve(len); } else { break; } } }private: void onStringMessage(const TcpConnectionPtr&, const string& message, Timestamp) { for (ConnectionList::iterator it = connections_.begin(); it != connections_.end(); ++it) { send(get_pointer(*it), message); } } void send(TcpConnection* conn, const std::string& message) { Buffer buf; buf.append(message.data(), message.size()); int32_t len = static_cast<int32_t>(message.size()); int32_t be32 = ntohl(len); buf.prepend(&be32, sizeof be32); conn->send((buf.retrieveAllAsString())); }private: static const int kHeaderLen = 4; typedef std::set<TcpConnectionPtr> ConnectionList; TcpServer server_; ConnectionList connections_;};int main(){ WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); { EventLoop loop; InetAddress serverAddr(7878); ChatServer server(&loop, serverAddr); server.start(); loop.loop(); } WSACleanup(); //char c; cin >> c;}
客户端,我们需要编写的回调函数有,连接的建立与断开,消息到来。还需要设计一个write函数发送数据。
#include <muduo_five\net\Tcpconnection.h>#include<muduo_five\net\TcpClient.h>#include <muduo_five\net\EventLoopThread.h>#include<string>#include <map>#include<mutex>#include <iostream>#include <stdio.h>using namespace std;class ChatClient : noncopyable{public: ChatClient(EventLoop* loop, const InetAddress& serverAddr) : client_(loop, serverAddr, "ChatClient") { client_.setConnectionCallback(std::bind(&ChatClient::onConnection, this, _1)); client_.setMessageCallback(std::bind(&ChatClient::onMessage, this, _1, _2, _3)); client_.enableRetry(); } void connect() { client_.connect(); } void disconnect() { client_.disconnect(); } void write(const std::string& message) { std::lock_guard<std::mutex> lock(mutex_); if (connection_) { send(get_pointer(connection_), message); } }private: void onConnection(const TcpConnectionPtr& conn) { std::lock_guard<std::mutex> lock(mutex_); if (conn->connected()) { connection_ = conn; } else { connection_.reset(); } } void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp receiveTime) { while (buf->readableBytes() >= kHeaderLen) { const void* data = buf->peek(); int32_t be32 = *static_cast<const int32_t*>(data); // SIGBUS const int32_t len = ntohl(be32); if (len > 65536 || len < 0) { conn->shutdown(); break; } else if (buf->readableBytes() >= len + kHeaderLen) { buf->retrieve(kHeaderLen); string message(buf->peek(), len); onStringMessage(conn, message, receiveTime); buf->retrieve(len); } else { break; } } }private: void onStringMessage(const TcpConnectionPtr&, const std::string& message, Timestamp) { printf("<<< %s\n", message.c_str()); } void send(TcpConnection* conn, const std::string& message) { Buffer buf; buf.append(message.data(), message.size()); int32_t len = static_cast<int32_t>(message.size()); int32_t be32 = ntohl(len); buf.prepend(&be32, sizeof be32); string temp = buf.retrieveAllAsString(); conn->send((temp)); }private: static const int kHeaderLen = 4; TcpClient client_; mutex mutex_; TcpConnectionPtr connection_;};int main( ){ WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); { EventLoopThread loop; InetAddress serverAddr("127.0.0.1", 7878); ChatClient client(loop.startThread(), serverAddr); client.connect(); std::string line; while (std::getline(std::cin, line)) { client.write(line); } client.disconnect(); } WSACleanup(); //char c; std::cin >> c;}
阅读全文
0 0
- 使用muduo编写聊天室
- 编写聊天室
- 使用muduo库编写回射服务器echo
- 使用python的twisted框架编写一个简单的聊天室
- 使用select.select编写聊天室服务器 《Python网络编程攻略》
- 使用python的twisted框架编写一个简单的聊天室
- vc--网络聊天室编写
- Socket编写点对点聊天室
- 简单聊天室的编写
- muduo网络库使用
- 编写基于PHP的聊天室
- 用PHP+MySql编写聊天室
- React编写聊天室(1)
- 我想编写一个聊天室客户端!
- Java编写多人聊天室
- Java编写简单的聊天室
- Linux多线程服务端编程:使用muduo C++网络库》(多年编写生产环境下多线程服务端程序经验之精华
- muduo网络库使用心得
- LeetCode No.41 First Missing Positive 题解
- while 死循环->小坑
- 从零开始学Scala系列(四)之数组集合1
- PIXHAWK+XPLANE-10硬件在环仿真
- laravel+easywechat微信扫码登录网站
- 使用muduo编写聊天室
- 第22节:富文本框和editor编辑器的处理
- 获取本地视频文件的缩略图
- html和CSS基础学习(三)
- mysql在linux下的安装
- dspic33E单片机IOPUWR复位原因之一 程序监控定时器
- bootstrap代码控制模态框的显示和隐藏
- 制作ubuntu16.04的docker镜像
- spring boot整合RabbitMQ(Direct模式)