Giter Site home page Giter Site logo

tokio_kcp's Introduction

tokio_kcp

Build And Test crates.io

A Kcp implementation for tokio

tokio_kcp's People

Contributors

banyc avatar devensiv avatar kunosayo avatar matrix-zhang avatar zonyitoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

tokio_kcp's Issues

Is it possible to provide an API that actively switches the underlying udp connection?

The underlying transport protocol of kcp implemented by this crate is udp

I found a phenomenon during actual use:
for the same udp connection (UDP data channel determined by source IP and source port and destination IP and destination port), the speed is normal for a period of time after the connection is established,

but As the connection duration increases, the transfer speed will drop so drastically that it is almost unusable (and not blocked)

Since the connection isn't blocked and the program doesn't try to create a new connection, this puts me in a bind - can only use a very low connection speed until I restart the app, then wait for the connection speed to fail again and start a new lap

So I would like to ask, is there a way for the client to actively (after disconnection) reconnect the API?

If not, is there any other way to solve the problem I am currently facing?

Never reaches EOF (or 0 bytes read)

I've been playing with this crate, but I can't get my read loop to stop (when it reads 0 bytes, like in your example).

On the client-side, I'm writing 80 bytes. On the server-side, the first loop iteration reads the whole 80 bytes and then keeps looping, even if my client has been dropped (closed).

I tried various options like stream: false, but couldn't make it work. I think this might be an issue with the async implementation specifically.

Any ideas?

Questions

Hi! I'm doing some research on modern networking libraries for games, with a focus on Rust.

I understand and have used a library like Enet for optionally reliable UDP packets. Is kcp a viable alternative to Enet? Can it have both reliable and unreliable packets working concurrently?

I'm really interested in the claims I've seen here.

What applications are best suited for kcp, and what motivated you in particular to write this Rust port?

Documentation and naming convention

  1. Documentation on every pub structs and functions is significant, which will allow users to get familiar with your library without looking into source code.

  2. Naming convention of Tokio's libraries are tokio-*, for example, tokio-io, tokio-uds, tokio-signal. So I propose this library should be renamed to tokio-kcp.

Bug: panic on session's "input channel closed"

I got this "input channel closed" panic the second time:

thread 'tokio-runtime-worker' panicked at 'input channel closed: SendError([..])', /Users/USERNAME/.cargo/git/checkouts/tokio_kcp-2bd8e2d6d03e8a8d/c909fd0/src/session.rs:259:50

tokio_kcp-2bd8e2d6d03e8a8d is the commit before modification of the version string 0.9.5 in Cargo.toml.

Previously I though it was caused by #28. But this version of tokio_kcp has already fixed that. So it might be another freshly discovered bug.

I investigated a little bit and spot some sus behaviors in session.rs.

First off, this line hits the panic:

self.input_tx.send(buf.to_owned()).await.expect("input channel closed")

Which means the corresponding input_rx got dropped before/during the input_tx.send call.

But input_rx lives inside the loop of session.rs:97 the whole time. It seems to me that the receiver never dies. However, io_task_handle represents that tokio task and will be aborted at session.rs:240:

io_task_handle.abort();

This line will kill input_rx and if unfortunately, input_tx was awaiting at that point, then the panic will be hit.

Question about 0.8.0 version stability

您好,我是Fourth - Rust实现的Layer 4代理的作者,目前使用了您开发的这个库来处理KCP连接,请问0.8.0版本目前稳定了么?因为没有在Crates.io上面找到您发布的0.8.0版本,最新的0.7.1版本也是4年前更新的了。
如果稳定了还烦请您发布一下新版本到Crates上面 :)

Bug: panic on receiving maliciously small packets

There is an assertion on kcp.rs:46:5 from crate kcp:

/// Read `conv` from raw buffer
pub fn get_conv(mut buf: &[u8]) -> u32 {
    assert!(buf.len() >= KCP_OVERHEAD as usize);

When the receiver gets hit with a packet smaller than KCP_OVERHEAD, the whole process will just die.

I triggered this by simply nc the port with some random characters.

KcpStream blocks tokio runtime when the connection closed both physically and abruptly

Background

Given that:

// `a`: KcpStream
// `b`: TimeoutStream<TcpStream>

let (mut a_r, mut a_w) = tokio::io::split(a);
let (mut b_r, mut b_w) = tokio::io::split(b);

let done = tokio::select! {
    res = tokio::io::copy(&mut a_r, &mut b_w) => {
        Done::FromAToB(res.map_err(TimedCopyBiError::FromAToB)?)
    }
    res = tokio::io::copy(&mut b_r, &mut a_w) => {
        Done::FromBToA(res.map_err(TimedCopyBiError::FromBToA)?)
    }
};

let res = match done {
    Done::FromAToB(a_to_b) => (a_to_b, 0),
    Done::FromBToA(b_to_a) => (0, b_to_a),
};
Ok(res)
  • The KcpStream is created by a KcpListener.
  • The TcpStream is connected to the origin server.

The blocking happens when the peer of the KcpStream switches off its network connection abruptly.

Behavior

netstat -an shows that there are a few TCP connections that are either stuck in CLOSE_WAIT or in ESTABLISHED while in both cases the Recv-Q are not zero numbers (but the Send-Qs are all zeros).

TimeoutStream will trigger an io::ErrorKind::Timeout if the read side remains idle for a whole minute. But it is defied by the aforementioned FDs.

It seems to me that the KcpStreams have somehow blocked the tokio runtime.

依赖版本建议

建议使用版本不用写死,如tokio = { version = "1.11", features = ["net", "sync", "rt"] }可换成tokio = { version = "1", features = ["net", "sync", "rt"] }

feature request: support modifying datagram to allow customizable protocol header

Firstly, thanks for the great repository!

Currently, tokio_kcp can't communicate with kcp-go because: beside kcp, kcp-go also adds other features that change its protocol header, e.g. crypto, crc, fec. It should be emphasized that these features are kcp-go specific.

Though, being compatible with kcp-go might be not the goal of tokio_kcp, I believe adding the ability for users to modify the datagram to support their own headers makes it possbile. It would also extend the potential usage of tokio_kcp.

one server, two client, conv not match

use your examples.
DEBUG kcp::kcp] input conv=2 expected conv=1 not match.
the test in listen.rs pass, a single listener does support multiple clients,
But I don't know how it happens.

KcpSession io_task_handle loop 不结束

server模式下, 循环不结束,是否应该添加 input_rx.recv() 失败时结束循环?

let io_task_handle = {
let session = session.clone();
tokio::spawn(async move {
let mut input_buffer = [0u8; 65536];

            loop {
                tokio::select! {
                    recv_result = udp_socket.recv(&mut input_buffer), if is_client => {
                        ...
                    }

                    // bytes received from listener socket
                    input_opt = input_rx.recv() => {
                        ...
                        } else {
                            // 这里结束循环???
                            break;
                        }
                    }
                }
            }
        })
    };

Hello

最近再看工作机会吗?看的话请联系我 微信: ole3021

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.