kcp icon indicating copy to clipboard operation
kcp copied to clipboard

ikcp_recv只有第一次能返回正确的值,其余都是返回-1

Open flyerSon opened this issue 5 years ago • 3 comments

请帮我看看哪里用错了。

这是server

#include "asio.hpp" #include #include #include #include "ikcp.h"

#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 #include #include #include "ikcp.h"

#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;

}

flyerSon avatar Nov 20 '19 06:11 flyerSon

你能不能修改下你代码的格式,看看 github 上面怎么正确的贴代码再说?

skywind3000 avatar Nov 20 '19 11:11 skywind3000

你能不能修改下你代码的格式,看看 github 上面怎么正确的贴代码再说?

实在抱歉,我把代码放在这个txt中,你帮忙看看,谢谢! main.txt

flyerSon avatar Nov 22 '19 22:11 flyerSon

题主我来帮你一把

#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();
}

brother-yan-web avatar Dec 27 '19 05:12 brother-yan-web