kcp
kcp copied to clipboard
ikcp_recv只有第一次能返回正确的值,其余都是返回-1
请帮我看看哪里用错了。
这是server
#include "asio.hpp"
#include
#define IPADDRESS "10.246.106.114" #define UDP_PORT 11000
using asio::ip::udp; using asio::ip::address;
uint32_t conv = 123; ikcpcb* service_kcp = NULL;
void Sender(const std::string& in) { asio::io_service io_service; udp::socket socket(io_service); udp::endpoint remote_endpoint = udp::endpoint(address::from_string(IPADDRESS), UDP_PORT); socket.open(udp::v4()); std::error_code err; auto sent = socket.send_to(asio::buffer(in), remote_endpoint, 0, err); socket.close(); std::cout << "Sent Payload --- " << sent << "\n"; }
int udp_out_put(const char* buf, int len, ikcpcb* kcp, void* user) { std::string in(buf, len); Sender(in); return 0; }
void do_recv(char* buf, int len) { std::string in(buf, len); std::cout << "kcp recv data:" << in << std::endl; }
uint32_t update_now_time_ms() { using namespace std; auto time_now = chrono::system_clock::now(); auto duration_in_ms = chrono::duration_castchrono::milliseconds(time_now.time_since_epoch()); return duration_in_ms.count(); }
struct Service { asio::io_service io_service; udp::socket socket{ io_service }; std::array<char, 1024> recv_buffer; udp::endpoint remote_endpoint;
int count = 100000;
void handle_receive(const std::error_code& error, size_t bytes_transferred) {
if (error) {
std::cout << "Receive failed: " << error.message() << "\n";
return;
}
std::string data(recv_buffer.begin(), recv_buffer.begin() + bytes_transferred);
ikcp_input(service_kcp, data.c_str(), bytes_transferred);
char kcp_buf[1000];
memset(kcp_buf, '\0', sizeof(kcp_buf));
int kcp_recvd_bytes = ikcp_recv(service_kcp, kcp_buf, sizeof(kcp_buf));
if (kcp_recvd_bytes > 0)
{
do_recv(kcp_buf, kcp_recvd_bytes);
}
std::cout << "kcp_byte:" << kcp_recvd_bytes << " udp received: " << data << " (" << error.message() << ")\n";
wait();
}
void wait() {
socket.async_receive_from(asio::buffer(recv_buffer),
remote_endpoint,
bind(&Service::handle_receive, this, std::placeholders::_1, std::placeholders::_2));
}
void receiver()
{
socket.open(udp::v4());
socket.bind(udp::endpoint(address::from_string(IPADDRESS), UDP_PORT));
wait();
std::cout << "Receiving\n";
io_service.run();
std::cout << "Receiver exit\n";
}
};
void init_ikcp() { service_kcp = ikcp_create(conv, (void*)1); service_kcp->output = udp_out_put; ikcp_nodelay(service_kcp,1,5,1,1); }
int main(int argc, char* argv[]) {
init_ikcp();
Service service;
std::thread r([&] { service.receiver(); });
while(true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
ikcp_update(service_kcp, update_now_time_ms());
}
r.join();
return 1;
}
这是client
#include "asio.hpp"
#include
#define IPADDRESS "10.246.106.114" #define UDP_PORT 11000
using asio::ip::udp; using asio::ip::address;
uint32_t conv = 123; ikcpcb* client_kcp = NULL;
void sender(const std::string& in) { asio::io_service io_service; udp::socket socket(io_service); udp::endpoint remote_endpoint = udp::endpoint(address::from_string(IPADDRESS), UDP_PORT); socket.open(udp::v4()); std::error_code err; auto sent = socket.send_to(asio::buffer(in), remote_endpoint, 0, err); socket.close(); std::cout << "Sent Payload --- " << sent << "\n"; }
int udp_out_put(const char* buf, int len, ikcpcb* kcp, void* arg) { std::string in(buf, len); sender(in); return 0; }
void do_recv(char* buf, int len) { std::string in(buf, len); std::cout << "recv data:" << in << std::endl; }
void init_ikcp() { client_kcp = ikcp_create(conv,NULL); client_kcp->output = udp_out_put; //ikcp_nodelay(client_kcp,1,5,1,1); }
uint32_t update_now_time_ms() { using namespace std; auto time_now = chrono::system_clock::now(); auto duration_in_ms = chrono::duration_castchrono::milliseconds(time_now.time_since_epoch()); return duration_in_ms.count(); }
int main(int argc, char* argv[]) { std::string input = argc > 1 ? argv[1] : "hello world"; std::cout << "Input is '" << input.c_str() << "'\nSending it to Sender Function...\n";
init_ikcp();
while(true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
ikcp_update(client_kcp, update_now_time_ms());
ikcp_send(client_kcp, input.c_str(), input.size());
}
return 1;
}
你能不能修改下你代码的格式,看看 github 上面怎么正确的贴代码再说?
题主我来帮你一把
#include <asio.hpp>
#include <array>
#include <thread>
#include <iostream>
#include "ikcp.h"
#define IPADDRESS "127.0.0.1" // "192.168.1.64"
#define UDP_PORT 13253
using asio::ip::udp;
using asio::ip::address;
ikcpcb *service_kcp = NULL,*client_kcp = NULL;
uint32_t conv = 123;
int32_t count = 1000;
std::mutex mutex;
void Sender(std::string in)
{
asio::io_service io_service;
udp::socket socket(io_service);
udp::endpoint remote_endpoint = udp::endpoint(address::from_string(IPADDRESS), UDP_PORT);
socket.open(udp::v4());
std::error_code err;
auto sent = socket.send_to(asio::buffer(in), remote_endpoint, 0, err);
socket.close();
std::cout << "Sent Payload --- " << sent << "\n";
}
struct Client
{
asio::io_service io_service;
udp::socket socket{io_service};
std::array<char, 1024> recv_buffer;
udp::endpoint remote_endpoint;
void handle_receive(const std::error_code& error, size_t bytes_transferred)
{
if (error)
{
std::cout << "Receive failed: " << error.message() << "\n";
return;
}
std::cout << "Received udp data: '" << std::string(recv_buffer.begin(), recv_buffer.begin()+bytes_transferred) << "' (" << error.message() << ")\n";
mutex.lock();
ikcp_input(client_kcp,recv_buffer.begin(),bytes_transferred);
char kcp_buf[1000];
memset(kcp_buf,'\0',sizeof(kcp_buf));
//不知为何,第一次是正确的,后面就一直返回-1,加锁也一样
int kcp_recvd_bytes = ikcp_recv(client_kcp,kcp_buf,sizeof(kcp_buf));
mutex.unlock();
if(kcp_recvd_bytes > 0)
{
std::string data(kcp_buf,kcp_recvd_bytes);
std::cout << "Received ikcp data:" << data << std::endl;
}
else
{
std::cout << "Received ikcp byte:" << kcp_recvd_bytes << std::endl;
}
if (--count > 0)
{
std::cout << "Count: " << count << "\n";
wait();
}
}
void wait()
{
socket.async_receive_from(asio::buffer(recv_buffer),
remote_endpoint,
bind(&Client::handle_receive, this, std::placeholders::_1, std::placeholders::_2));
}
void Receiver()
{
socket.open(udp::v4());
socket.bind(udp::endpoint(address::from_string(IPADDRESS), UDP_PORT));
wait();
std::cout << "Receiving\n";
io_service.run();
std::cout << "Receiver exit\n";
}
};
int udp_out_put(const char *buf,int len,ikcpcb *kcp,void *user)
{
std::string in(buf,len);
Sender(in);
return 0;
}
void init_ikcp()
{
service_kcp = ikcp_create(conv,(void*)0);
service_kcp->output = udp_out_put;
client_kcp = ikcp_create(conv,(void*)1);
client_kcp->output = udp_out_put;
}
uint32_t update_now_time_ms()
{
using namespace std;
auto time_now = chrono::system_clock::now();
auto duration_in_ms = chrono::duration_cast<chrono::milliseconds>(time_now.time_since_epoch());
return duration_in_ms.count();
}
int main(int argc, char *argv[])
{
init_ikcp();
Client client;
std::thread r([&] { client.Receiver(); });
std::string input = argc>1? argv[1] : "hello world";
std::cout << "Input is '" << input.c_str() << "'\nSending it to Sender Function...\n";
for (int i = 0; i < count; ++i) {
std::this_thread::sleep_for(std::chrono::milliseconds(200));
ikcp_update(service_kcp,update_now_time_ms());
mutex.lock();
ikcp_update(client_kcp,update_now_time_ms());
mutex.unlock();
ikcp_send(service_kcp,input.c_str(),input.size());
}
r.join();
}