C++实现websocket服务端客户端(基于boost,亲测可行!)

这篇具有很好参考价值的文章主要介绍了C++实现websocket服务端客户端(基于boost,亲测可行!)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

  整篇文章基本参考了https://blog.csdn.net/jianghuan0122/article/details/123528907,文章记录了如何在现有条件下实现该参考示例(参考示例存在报错,并且参考示例没有介绍环境安装,正确源码附于文末)

  自身环境:ubuntu18.04+gcc7.5.0+boost1.7,3

环境配置

  gcc或者g++一般都有,这里主要介绍一下boost的配置方法
  执行如下代码:

wget https://boostorg.jfrog.io/artifactory/main/release/1.73.0/source/boost_1_73_0.tar.bz2 --no-check-certificate
tar xvf boost_1_73_0.tar.bz2
cd boost_1_73_0
./bootstrap.sh --prefix=/usr 
./b2 
sudo ./b2 install
cat /usr/include/boost/version.hpp | grep "BOOST_LIB_VERSION"

  装完后发现还是会报错:#include <boost/beast/core.hpp> no such file
  这个时候再加一个:

sudo apt-get install libboost-all-dev

  然后编译执行代码就可以了,在这里说明下我不太确定是否要执行那个apt-get,理论上前面是源码编译就没问题了,后面估计是默认库的安装,但是我当时没太注意顺序,两个都做了一下才成功、
boost安装参考:https://blog.csdn.net/HandsomeHong/article/details/128813619

  还有就是参考的示例存在报错,是关于C++11codecvt部分的,没有时间去改bug了,就直接换了一套string和wstring的相互转化,主要参考了:https://blog.csdn.net/juluwangriyue/article/details/115680861
  这个需要加两个头文件#include <wchar.h> #include <locale.h>

示例源码

server.cpp(需要换自己的IP)

#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <string>
#include <thread>
#include <codecvt>
#include <wchar.h>
#include <locale.h>
namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
std::wstring string_to_wstring(const std::string& str)
{
	std::wstring r;
    const char *source = str.c_str();
    wchar_t *dest = NULL;
    int len = 0;
    int ret = 0;
    len = strlen(source) + 1;
    if(len <= 1)
        return 0;
    dest = new wchar_t[len];
    ret = mbstowcs(dest, source, len);
    r = std::wstring(dest);
    delete[] dest;
	return r;
}

std::string wstring_to_string(const std::wstring& ws)
{
	std::string r = "";
    const wchar_t *source = ws.c_str();
    char *dest = NULL;
    int len = 0;
    int ret = 0;
    len = wcslen(source) + 1;
    if(len <= 1)
        return 0;
    dest = new char[len*sizeof(wchar_t)];
    ret = wcstombs(dest, source, len*sizeof(wchar_t));
    r = std::string(dest);
    delete[] dest;
	return r;
}

std::string ansi_to_utf8(const std::string& s)
{
	static std::wstring_convert<std::codecvt_utf8<wchar_t> > conv;
	return conv.to_bytes(string_to_wstring(s));
}
std::string utf8_to_ansi(const std::string& s)
{
	static std::wstring_convert<std::codecvt_utf8<wchar_t> > conv;
	return wstring_to_string(conv.from_bytes(s));
}
 
void do_session(tcp::socket& socket)
{
	try
	{
		websocket::stream<tcp::socket> ws{ std::move(socket) };
		ws.set_option(websocket::stream_base::decorator(
			[](websocket::response_type& res)
		{
			res.set(http::field::server,
				std::string(BOOST_BEAST_VERSION_STRING) +
				" websocket-server-sync");
		}));
		ws.accept();//等待客户端连接
		for (;;)
		{
			std::string text = "{\"send\": 123}"; // 发送的消息内容,以一个json数据包的格式	
			ws.write(net::buffer(ansi_to_utf8(text)));// 发送消息
		
			beast::flat_buffer buffer;// 这个缓冲区将保存传入的消息
			ws.read(buffer);// 读取一条消息
			auto out = beast::buffers_to_string(buffer.cdata());
			std::cout << utf8_to_ansi(out) << std::endl;
 
			sleep(1); //等待1秒
 
			/*
			// 将读取到的消息再发送回客户端
			ws.text(ws.got_text());
			ws.write(buffer.data());
			*/
		}
	}
	catch (beast::system_error const& se)
	{
		if (se.code() != websocket::error::closed)
			std::cerr << "Error: " << se.code().message() << std::endl;
	}
	catch (std::exception const& e)
	{
		std::cerr << "Error: " << e.what() << std::endl;
	}
}
 
int main(int argc, char* argv[])
{
	try
	{
		auto const address = net::ip::make_address("192.168.1.116");//绑定ip地址
		auto const port = static_cast<unsigned short>(std::atoi("20000"));//绑定端口号
		net::io_context ioc{ 1 };
		tcp::acceptor acceptor{ ioc,{ address, port } };
		for (;;)
		{
			tcp::socket socket{ ioc };
			acceptor.accept(socket);
			// 开启线程等待客户端的连接请求
			std::thread{ std::bind(&do_session,std::move(socket)) }.detach();
		}
	}
	catch (const std::exception & e)
	{
		std::cerr << "Error: " << e.what() << std::endl;
		return EXIT_FAILURE;
	}
}

client.cpp(需要换自己的IP)

#include<time.h> 
 
#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdlib>
#include <iostream>
#include <string>
#include <locale>
#include <codecvt>
#include <wchar.h>
#include <locale.h>
namespace beast = boost::beast;         // from <boost/beast.hpp>
namespace http = beast::http;           // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio;            // from <boost/asio.hpp>
using tcp = boost::asio::ip::tcp;       // from <boost/asio/ip/tcp.hpp>
std::wstring string_to_wstring(const std::string& str)
{
	std::wstring r;
    const char *source = str.c_str();
    wchar_t *dest = NULL;
    int len = 0;
    int ret = 0;
    len = strlen(source) + 1;
    if(len <= 1)
        return 0;
    dest = new wchar_t[len];
    ret = mbstowcs(dest, source, len);
    r = std::wstring(dest);
    delete[] dest;
	return r;
}

std::string wstring_to_string(const std::wstring& ws)
{
	std::string r = "";
    const wchar_t *source = ws.c_str();
    char *dest = NULL;
    int len = 0;
    int ret = 0;
    len = wcslen(source) + 1;
    if(len <= 1)
        return 0;
    dest = new char[len*sizeof(wchar_t)];
    ret = wcstombs(dest, source, len*sizeof(wchar_t));
    r = std::string(dest);
    delete[] dest;
	return r;
}

std::string ansi_to_utf8(const std::string &s)
{
	static std::wstring_convert<std::codecvt_utf8<wchar_t> > conv;
	return conv.to_bytes(string_to_wstring(s));
}
std::string utf8_to_ansi(const std::string& s)
{
	static std::wstring_convert<std::codecvt_utf8<wchar_t> > conv;
	return wstring_to_string(conv.from_bytes(s));
}
 
int main(int argc, char** argv)
{
	int num = 0;//接收到包的个数
 
	try
	{
		net::io_context ioc;
		tcp::resolver resolver{ ioc };
		websocket::stream<tcp::socket> ws{ ioc };
		auto const address = net::ip::make_address("192.168.1.116"); //服务器地址
		auto const port = static_cast<unsigned short>(std::atoi("20000"));//服务器端口号
		tcp::endpoint endpoint{ address, port };
		auto const results = resolver.resolve(endpoint);
		// 在我们从查找中获得的IP地址上建立连接
		net::connect(ws.next_layer(), results.begin(), results.end());
		ws.set_option(websocket::stream_base::decorator(
			[](websocket::request_type& req)
		{
			req.set(http::field::user_agent,
				std::string(BOOST_BEAST_VERSION_STRING) +
				" websocket-client-coro");
		}));
 
		ws.handshake("192.168.1.116", "/"); //发送握手消息
		while (true)
		{
			beast::flat_buffer buffer;//创建一个缓冲区用于存放接收到的消息	
			ws.read(buffer);// 读取一条消息到缓冲区
			std::string out;
			out = beast::buffers_to_string(buffer.cdata());
			std::cout << utf8_to_ansi(out) << std::endl; //输出消息到控制台显示
 
			//解析json数据包
			if (out != "") //未解析json,只是判断内容是否为空
			{		
				std::string text = "{\"result\": 0}";//发送的消息内容,以一个json数据包的格式
				ws.write(net::buffer(ansi_to_utf8(text))); // 发送消息
 
				num++;//增加计数
 
				//当前时间
				time_t now = time(NULL);
				tm* tm_t = localtime(&now);
				std::stringstream ss;
				ss << tm_t->tm_year + 1900 << "-" << tm_t->tm_mon + 1 << "-" << tm_t->tm_mday
					<< " " << tm_t->tm_hour << ":" << tm_t->tm_min << ":" << tm_t->tm_sec;
 
				std::cout << "当前时间:" << ss.str() << ",第 " << num << "个"<<std::endl;
			}			
		}
	
		ws.close(websocket::close_code::normal);// 关闭WebSocket连接
	}
	catch (std::exception const& e)
	{
		std::cerr << "Error: " << e.what() << std::endl;
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}

编译的命令如下:文章来源地址https://www.toymoban.com/news/detail-670554.html

g++ server.cpp -o server -lpthread -std=c++11
g++ client.cpp -o client -std=c++11 -lpthread

到了这里,关于C++实现websocket服务端客户端(基于boost,亲测可行!)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot+WebSocket实现服务端、客户端

    小编最近一直在使用springboot框架开发项目,毕竟现在很多公司都在采用此框架,之后小编也会陆续写关于springboot开发常用功能的文章。 什么场景下会要使用到websocket的呢? websocket主要功能就是实现网络通讯,比如说最经典的客服聊天窗口、您有新的消息通知,或者是项目与

    2024年02月13日
    浏览(50)
  • Java实现WebSocket客户端和服务端(简单版)

    天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。 写在前面: WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket通信协议于

    2024年02月08日
    浏览(48)
  • SpringBoot集成WebSocket实现客户端与服务端通信

    话不多说,直接上代码看效果! 一、服务端: 1、引用依赖 2、添加配置文件 WebSocketConfig 3、编写WebSocket服务端接收、发送功能   声明接口代码:   实现类代码: 4、如果不需要实现客户端功能,此处可选择前端调用,奉上代码 二、客户端: 1、引用依赖 2、自定义WebSocket客

    2024年01月23日
    浏览(54)
  • Python3实现WebSocket服务端与客户端通信

    Python3实现WebSocket服务端与客户端通信 WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket通信更加轻便、高效,比传统的HTTP通信更省流量和更快速,因此在Web应用领域越来越受欢迎。Python 3提供了内置的websocket库,可以方便地实现WebSocket服务端和客户端的通信。

    2024年02月12日
    浏览(53)
  • Spring Boot 集成 WebSocket 实现服务端推送消息到客户端

          假设有这样一个场景:服务端的资源经常在更新,客户端需要尽量及时地了解到这些更新发生后展示给用户,如果是 HTTP 1.1,通常会开启 ajax 请求询问服务端是否有更新,通过定时器反复轮询服务端响应的资源是否有更新。                         在长时间不更新

    2024年02月16日
    浏览(60)
  • SpringBoot集成WebSocket实现客户端与服务端长连接通信

    场景: 1、WebSocket协议是用于前后端长连接交互的技术,此技术多用于交互不断开的场景。特点是连接不间断、更轻量,只有在关闭浏览器窗口、或者关闭浏览器、或主动close,当前会话对象才会关闭。 2、相较于 Http/Https 通信只能由客户端主动发起请求,而 Socket 通信不仅能

    2024年02月02日
    浏览(60)
  • 【Java】SpringBoot快速整合WebSocket实现客户端服务端相互推送信息

    目录 什么是webSocket? webSocket可以用来做什么? WebSocket操作类 一:测试客户端向服务端推送消息 1.启动SpringBoot项目 2.打开网站 3.进行测试消息推送 4.后端进行查看测试结果 二:测试服务端向客户端推送消息 1.接口代码 2.使用postman进行调用 3.查看测试结果         WebSocke

    2024年01月20日
    浏览(62)
  • Java:SpringBoot整合WebSocket实现服务端向客户端推送消息

    思路: 后端通过websocket向前端推送消息,前端统一使用http协议接口向后端发送数据 本文仅放一部分重要的代码,完整代码可参看github仓库 websocket 前端测试 :http://www.easyswoole.com/wstool.html 依赖 项目目录 完整依赖 配置 WebSocketServer.java 前端页面 websocket.html 前端逻辑 index.js 参

    2024年02月04日
    浏览(54)
  • WebSocket 详解,以及用QWebSocket 实现服务端和客户端(含代码例子)

    目录 前言: 1、WebSocket 诞生背景 2、WebSocket的特点: 3、 WebSocket 简介 4、WebSocket 优点 5、QWebSocket通讯—客户端: 6、QWebSocket通讯—服务端: 前言:         要是对WebSocket 的基本知识都了解了,可以直接移步,实际如何使用这个类 (二) 用QWebSocket 实现服务端和客户端(

    2024年02月16日
    浏览(49)
  • 如何将本地websocket服务端从本地暴露至公网实现客户端远程连接

    1. Java 服务端demo环境 jdk1.8 框架:springboot+maven 工具IDEA 2. 在pom文件引入第三包封装的netty框架maven坐标 注意:pom文件里需注释掉springbootweb启动器,web启动器默认是tomcat服务启动,会和netty服务冲突 3. 创建服务端,以接口模式调用,方便外部调用 4. 启动服务,出现以下信息表示启动成功

    2024年04月10日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包