如何解决boost :: asio使用带有字符串的boost :: array构建缓冲区
我正在通过遵循文档中的示例并对其进行扩展来学习如何使用boost :: asio。 示例Daytime.4和Daytime.5显示了如何实现同步udp服务器-客户端通信。该示例通过构造一个char类型的boost数组,然后在该数组之外构造一个boost缓冲区来发送数据:
//structure
-frontend
-node_modules
-src
-component
-setupTests.ts
-App.tsx
-etc
-babel.config.js
-jest.config.js
-package.json
-tsconfig.json
//package.json
"scripts": {
"start": "react-scripts start","build": "react-scripts build","test": "react-scripts test","test:coverage": "react-scripts test --coverage --runInBand --watchAll=false",}
"devDependencies": {
"@babel/core": "^7.12.1","@babel/preset-env": "^7.12.1","@babel/preset-react": "^7.12.1","@testing-library/jest-dom": "^5.11.4","@types/jest": "^26.0.14","jest": "^26.5.3","ts-jest": "^26.4.1","@types/enzyme": "^3.10.7","@types/enzyme-adapter-react-16": "^1.0.6","@types/jsdom": "^16.2.4","enzyme": "^3.11.0","enzyme-adapter-react-16": "^1.15.5","eslint": "^7.9.0","@typescript-eslint/eslint-plugin": "^4.1.1","@typescript-eslint/parser": "^4.1.1","eslint-config-prettier": "^6.11.0","eslint-plugin-prettier": "^3.1.4","eslint-plugin-react": "^7.20.6","prettier": "^2.1.2"
}
//jest.config.js
module.exports = {
preset: 'ts-jest',snapshotSerializers: ['enzyme-to-json/serializer'],testEnvironment: 'node',transform: {
'^.+\\.tsx?$': 'ts-jest'
},"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(js|ts|tsx)?$",modulefileExtensions: ['ts','tsx','js','jsx','json','node'],setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],collectCoverage: true,transformIgnorePatterns: ["[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"]
};
//setupTests.ts
import enzyme from "enzyme";
import Adapter from "enzyme-adapter-react-16";
import "@testing-library/jest-dom";
enzyme.configure({ adapter: new Adapter() });
//ts.config.json
{
"compilerOptions": {
"target": "es5","lib": ["dom","dom.iterable","esnext"],"allowJs": true,"skipLibCheck": true,"esModuleInterop": true,"allowSyntheticDefaultImports": true,"forceConsistentCasingInFileNames": true,"module": "esnext","moduleResolution": "node","resolveJsonModule": true,"isolatedModules": true,"jsx": "react","strict": true,"noEmit": true,// we don't need to generate files as react works directly
"types": [
"jest","node","react"
] },"include": ["src"],"exclude": ["./node_modules","*.js"]
}
//babel.config.js
module.exports = {
presets: [
['@babel/preset-env',{targets: {node: 'current'}}],+ '@babel/preset-typescript',],};
//Burger.tsx
import React from "react";
import "./burger.css";
//clickEvent
type Props = {
// eslint-disable-next-line @typescript-eslint/ban-types
clickEvent: Function;
isItClicked: boolean;
};
const Burger: React.FC<Props> = (props) => {
// eslint-disable-next-line react/prop-types
const { clickEvent,isItClicked } = props;
return (
<div
data-testid="no-classes"
id="burger"
onClick={() => clickEvent()}
className={isItClicked ? "cross" : ""}
>
<span></span>
<span></span>
<span></span>
</div>
);
};
export default Burger;
//burger.css
#burger {
position: absolute;
}
//burger.test.js
import * as React from 'react';
import Burger from "../Burger.tsx"
import { mount } from 'enzyme';
describe("We test the innerHTML of the burger",() => {
let wrapper;
beforeEach(() => {
wrapper = mount(<Burger />);
});
test("Snapshot burger ",() => {
//It works
expect(wrapper).toMatchSnapshot();
});
test("burger style css",() => {
//it doesn't work
expect(wrapper.find("#burger")).toHaveStyle('position: absolute')
});
});
还有一个示例,他们采用std :: string并将其直接传递给缓冲区构造函数:
boost::array<char,1> send_buf = {{ 0 }};
socket.send_to(boost::asio::buffer(send_buf),receiver_endpoint);
到目前为止一切顺利。我现在尝试填充字符串数组并将该数组发送到udp服务器。这总是导致服务器在实际消息之前接收到垃圾字符。 当我这样构造发送缓冲区时:
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
socket.send_to(boost::asio::buffer(message),remote_endpoint,ignored_error);
我得到这样的输出:std::string message = "I am still here";
boost::array<std::string,1> send_buf2 = {{ message}};
socket.send_to(boost::asio::buffer(send_buf2),receiver_endpoint);
当我的数组是这样构造的:
|��I am still here
我在输出中仅得到内存垃圾字符。两种情况下的接收长度均为32(字符)。
服务器读取如下消息:
boost::array<std::string,1> send_buf2 = {{ "I am still here" }};
这是构造发送缓冲区的一种不好的方法吗?还是有解决此问题的方法?
解决方法
您调用buffer
函数的以下重载:
template<
typename PodType,std::size_t N>
mutable_buffer buffer(
boost::array< PodType,N > & data);
仅适用于POD。 string
不是POD类型。
boost asio中的缓冲区可以视为一对:指向数据的指针和数据的长度。在您的情况下,您将创建一个缓冲区,该缓冲区指向字符串的二进制表示形式,而不是由字符串管理的数据-std :: string内部指针所指向的字符序列(使用小字符串优化时,此输出|��I am still here
是可能的)。这就解释了为什么要获得32个字节,对于实现库来说,它仅为sizeof(std::string)
。
如果要发送由boost :: array字符串管理的数据,则可以使用复合缓冲区:
const boost::array<std::string,2> a{{"I am still here","xxx"}};
std::vector<boost::asio::const_buffers_1> v;
v.push_back(boost::asio::buffer(a[0]));
v.push_back(boost::asio::buffer(a[1]));
创建缓冲区向量,并将基于std::string
创建的缓冲区一一添加到该向量。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。