Unit-X / kcp-cpp

C++ Wrapper around KCP
MIT License
82 stars 27 forks source link

When receiving a relatively large data packet (larger than 8192), the last packet will block for 8 to 10 seconds at mKissnetSocket.recv(receiveBuffer). #10

Open luodaoyi opened 7 months ago

luodaoyi commented 7 months ago

When receiving a relatively large data packet (larger than 8192), the last packet will block for 8 to 10 seconds at mKissnetSocket.recv(receiveBuffer).

        const uint64_t tickStart = GetTickCount64(); 
        auto[received_bytes, status] = mKissnetSocket.recv(receiveBuffer); 
        const auto tick = GetTickCount64() - tickStart;
        if (tick > 1000) {
            KCP_LOGGER(false, LOGG_NOTIFY, "Recv Time:  " << tick);   // <----------  10 Second !!!!
        }

The server is developed using kcp-go with the following parameters:

    kcpConn.SetNoDelay(1, 10,2,1)
    kcpConn.SetWindowSize(128, 128)

kcp-cpp:

    KCPSettings lSettingsClient;
    lSettingsClient.mNoDelay = true;
    lSettingsClient.mInterval = 10;
    lSettingsClient.mResend = 2;
    lSettingsClient.mFlow = false;
    lSettingsClient.mMtu = 1400;
    lSettingsClient.mSndWnd = 128;
    lSettingsClient.mRcvWnd = 128;
andersc commented 7 months ago

change

define KCP_MAX_BYTES 4096

in KCPNet.cpp line 13

to your maximum value

Let us know how it works after the change.

Also if you send a lot of data then you should lower lSettingsClient.mInterval to something lower than 10.. (meaning flush the buffers every 10 milliseconds).. Set to 1 for maximum throughput.

KCPSettings lSettingsClient;
lSettingsClient.mInterval = 1;
luodaoyi commented 7 months ago

change

define KCP_MAX_BYTES 4096

in KCPNet.cpp line 13

to your maximum value

Let us know how it works after the change.

Also if you send a lot of data then you should lower lSettingsClient.mInterval to something lower than 10.. (meaning flush the buffers every 10 milliseconds).. Set to 1 for maximum throughput.

KCPSettings lSettingsClient;
lSettingsClient.mInterval = 1;

If KissnetSocket.recv is blocked, which means recvfrom is also blocked, does it imply that the data from the server (kcp-go) has not been sent?

luodaoyi commented 7 months ago
#define KCP_MAX_BYTES  10 * 1024 

The problem remains that the blocking at KissnetSocket.recv -> recvfrom lasts for 9 seconds, which indicates that the data has not been sent by kcp-go. recvfrom is the underlying UDP function.

andersc commented 7 months ago

Could be the case. The interoperability with KCP-GO has never been verified by us. KCP-CPP 'just' wraps the original KCP-C implementation and ads a thin socket layer on-top, while KCP-GO is a re-write of the KCP protocol.

My recommendation is to contact the maintainers of KCP-GO and ask them if the GO implementation has been verified to work with the orignal KCP-C Library using what settings.

/A

luodaoyi commented 7 months ago

Could be the case. The interoperability with KCP-GO has never been verified by us. KCP-CPP 'just' wraps the original KCP-C implementation and ads a thin socket layer on-top, while KCP-GO is a re-write of the KCP protocol.

My recommendation is to contact the maintainers of KCP-GO and ask them if the GO implementation has been verified to work with the orignal KCP-C Library using what settings.

/A

Thank you !

luodaoyi commented 4 months ago

Could you please implement a Forward Error Correction (FEC) feature for the KCP library? The author of KCP has recommended using FEC to reduce data loss during transmission. This would greatly enhance the reliability and performance of our application.

https://github.com/skywind3000/kcp/wiki/Network-Layer