- 接收应用程序的缓冲区大小
我不知道,但由于某种原因,你选择了只读2048
每字节接收。有什么特别的原因?我已将其更改回客户正在写入的实际大小。您可能只是在服务器接收部分排队更多的数据。
新的服务器代码:
#include <thread>
#include <chrono>
#include <vector>
#include <signal.h>
#include <asio.hpp>
#include <system_error>
namespace
{
bool keepGoing = true;
void shutdown(int)
{
keepGoing = false;
}
std::size_t bytesAccum = 0;
void justReceive(std::error_code ec, std::size_t bytesReceived,
asio::ip::tcp::socket &socket, std::vector<unsigned char> &buffer)
{
bytesAccum += bytesReceived;
/*
auto end = buffer.begin() + bytesReceived;
for (auto it = buffer.begin(); it != end; ++it)
{
if (*it == 'e')
{
std::printf("server got: %lu\n", bytesAccum);
bytesAccum = 0;
}
}
*/
socket.async_receive(
asio::buffer(buffer),
0,
[&] (auto ec, auto bytes) {
justReceive(ec, bytes, socket, buffer);
});
}
}
int main(int, char **)
{
signal(SIGINT, shutdown);
asio::io_service io;
asio::io_service::work work(io);
std::thread t1([&]() { io.run(); });
std::thread t2([&]() { io.run(); });
std::thread t3([&]() { io.run(); });
std::thread t4([&]() { io.run(); });
asio::ip::tcp::acceptor acceptor(io,
asio::ip::tcp::endpoint(
asio::ip::address::from_string("127.0.0.1"), 1234));
asio::ip::tcp::socket socket(io);
// accept 1 client
std::vector<unsigned char> buffer(131072, 0);
acceptor.async_accept(socket, [&socket, &buffer](std::error_code ec)
{
// options
//socket.set_option(asio::ip::tcp::no_delay(true));
//socket.set_option(asio::socket_base::receive_buffer_size(8192 * 2));
//socket.set_option(asio::socket_base::send_buffer_size(8192));
socket.async_receive(
asio::buffer(buffer),
0,
[&](auto ec, auto bytes) {
justReceive(ec, bytes, socket, buffer);
});
});
while (keepGoing)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
}
io.stop();
t1.join();
t2.join();
t3.join();
t4.join();
std::printf("server: goodbye\n");
}
新的客户端代码:
#include <thread>
#include <chrono>
#include <vector>
#include <signal.h>
#include <asio.hpp>
#include <system_error>
namespace
{
bool keepGoing = true;
void shutdown(int) { keepGoing = false; }
}
int main(int, char **)
{
signal(SIGINT, shutdown);
asio::io_service io;
asio::io_service::work work(io);
std::thread t1([&]() { io.run(); });
std::thread t2([&]() { io.run(); });
std::thread t3([&]() { io.run(); });
std::thread t4([&]() { io.run(); });
asio::ip::tcp::socket socket(io);
auto endpoint = asio::ip::tcp::resolver(io).resolve({
"127.0.0.1", "1234" });
asio::connect(socket, endpoint);
// options to test
//socket.set_option(asio::ip::tcp::no_delay(true));
//socket.set_option(asio::socket_base::receive_buffer_size(8192));
//socket.set_option(asio::socket_base::send_buffer_size(8192 * 2));
std::vector<unsigned char> buffer(131072, 0);
buffer.back() = 'e';
std::chrono::time_point<std::chrono::system_clock> last =
std::chrono::system_clock::now();
std::chrono::duration<double> delta = std::chrono::seconds(0);
std::size_t bytesSent = 0;
while (keepGoing)
{
// blocks during send
asio::write(socket, asio::buffer(buffer));
//socket.send(asio::buffer(buffer));
// accumulate bytes sent
bytesSent += buffer.size();
// accumulate time spent sending
delta += std::chrono::system_clock::now() - last;
last = std::chrono::system_clock::now();
// print information periodically
if (delta.count() >= 5.0)
{
std::printf("Mbytes/sec: %f, Gbytes/sec: %f, Mbits/sec: %f, Gbits/sec: %f\n",
bytesSent/1.0e6/delta.count(),
bytesSent/1.0e9/delta.count(),
8 * bytesSent/1.0e6/delta.count(),
8 * bytesSent/1.0e9/delta.count());
// reset accumulators
bytesSent = 0;
delta = std::chrono::seconds(0);
}
}
io.stop();
t1.join();
t2.join();
t3.join();
t4.join();
std::printf("client: goodbyte\n");
}
注:我用的asio
单机版,但所报告的OP结果是我的机器是对重复性:
MacBook Pro Yosemite - 2.6 GHz Intel Core i5处理器 - 8GB DDR3内存条 。
我通过评论所有套接字的接收和发送缓冲区大小选项并将所需的调整大小推迟到TCP自动调整而将其提升至3GBps。此外,我更改了服务器接收代码,以避免迭代缓冲区,这是浪费。我在http://melpon.org/wandbox/permlink/UUlmqwH5tlD4Ah4f更改了代码 – Arunmu
最好看看iperf在做什么。可能是它使用一些零拷贝机制来发送? – Arunmu
哦..我没有看到它是iperf每秒33G'bits'。然后我的变化是24Gbits每秒:)。足够接近,但我相信很多事情都可以完成。再次重新运行,这次显示了大约30 Gbps的速度。 – Arunmu