在使用ikcp配合UVW库中的udp通信时,想让通信速度达到千兆的同时可以在网络不稳定时仍可以正确传输文件,但是发现在将kcp的mtu设置为1400时即使
ikcp_nodelay(kcp, 1, 1, 2, 1);
ikcp_wndsize(kcp, 1200, 1200);
const size_t buff_size = 15000;
这样设置速度也只能达到70MB/S左右(这是在不调mtu的情B况下尝试出来的最大速度,调用update的频率为1毫秒一次)
但是当把发送端的mtu设置到2800时(ikcp_setmtu(kcp, 2800);)速度就可以达到110MB/s,但是好像是因为ip分片的原因,在网络丢包率有2%的时候,传输就会卡到不可用的状态。不知道还有没有什么别的办法可以同时满足速度和稳定性。(也不能开启巨型帧)
整体代码如下(发送端):
int kcp_output(const char *buf, int len, ikcpcb *kcp, void *user) {
char* send_data = const_cast<char*>(buf);
auto udp_send = static_cast<uvw::udp_handle*>(user);
int send_res = udp_send->send("192.168.0.128", 12344, send_data, len);
if(send_res < 0) {
std::cout << "send falid" << std::endl;
}
return send_res;
}
void readfile(ikcpcb *kcp, std::string filePath, int buff_size) {
std::ifstream file(filePath, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Failed to open file: " << filePath << std::endl;
return;
}
std::cout << "File Reading..." << std::endl;
std::vector<char> buffer(buff_size);
size_t pos = filePath.find_last_of("/\\");
std::string Name = filePath.substr(pos + 1);
ikcp_send(kcp, &Name[0], static_cast<int>(Name.length()));
while (file.read(buffer.data(), buffer.size())) {
ikcp_send(kcp, buffer.data(), static_cast<int>(file.gcount()));
}
if (file.gcount() > 0) {
ikcp_send(kcp, buffer.data(), static_cast<int>(file.gcount()));
}
}
void start() {
std::cout << "Enter the file path and file name:" << std::endl;
std::string filePath = "d:/ikcptest.zip";
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed\n";
return;
}
auto loop = uvw::loop::get_default();
auto udp_send = loop->resource<uvw::udp_handle>();
int bindres = udp_send->bind("192.168.0.22", INADDR_ANY);
if(bindres < 0) {
std::cout << "send bind falid" << std::endl;
}
ikcpcb *kcp = ikcp_create(0x11223344, static_cast<void*>(udp_send.get()));
ikcp_setoutput(kcp, kcp_output);
ikcp_nodelay(kcp, 1, 1, 2, 1);
ikcp_wndsize(kcp, 1200, 1200);
const size_t buff_size = 15000;
auto udp_recv = loop->resource<uvw::udp_handle>();
int res = udp_recv->bind("192.168.0.22", 12355);
char kcp_buf[1024];
udp_recv->on<uvw::udp_data_event>([&](const uvw::udp_data_event &event, uvw::udp_handle &handle) {
memset(kcp_buf, 0, sizeof(kcp_buf));
int ret = ikcp_input(kcp, event.data.get(), event.length);
int res = ikcp_recv(kcp, kcp_buf, sizeof(kcp_buf));
udp_recv->recv();
});
udp_recv->recv();
auto timer = loop->resource<uvw::timer_handle>();
std::chrono::milliseconds timeout(0);
std::chrono::milliseconds repeat(1);
timer->on<uvw::timer_event>([&](const uvw::timer_event&, uvw::timer_handle&){
ikcp_update(kcp, GetTickCount());
});
timer->start(timeout, repeat);
std::thread(readfile, kcp, filePath, buff_size).detach();
loop->run();
WSACleanup();
}
int main(int argc, char *argv[])
{
start();
return 0;
}