Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read on StreamHandle returns UnexpectedEof instead of Ok(0) #360

Closed
umiro opened this issue Aug 30, 2022 · 4 comments · Fixed by #362
Closed

read on StreamHandle returns UnexpectedEof instead of Ok(0) #360

umiro opened this issue Aug 30, 2022 · 4 comments · Fixed by #362

Comments

@umiro
Copy link

umiro commented Aug 30, 2022

可能与 #205 有关。

我用io::copy转发数据,发现StreamHandle在另一端调用shutdownread总是返回一个unexpectedeof,但Tokio的TcpStream在这种情况下返回Ok(0)io::copy也依赖该行为,是有意这样设计的吗?

测试代码-yamux
测试代码-tokio

@umiro umiro changed the title poll_read on streamhandle returns unexpectedeof instead of Ok(0) read on StreamHandle returns UnexpectedEof instead of Ok(0) Aug 30, 2022
@driftluo
Copy link
Collaborator

我认为这应该是一个实现错误

StreamState::RemoteClosing => {
debug!("closed(EOF)");
let _ignore = self.send_close();
Err(io::ErrorKind::UnexpectedEof.into())

根据约定,这里应该返回 Ok(0)

Poll::Ready(Ok(())) means that data was immediately read and placed into the output buffer. The amount of data read can be determined by the increase in the length of the slice returned by ReadBuf::filled. If the difference is 0, EOF has been reached.

@umiro
Copy link
Author

umiro commented Aug 30, 2022

或许可以在这里把状态切换到Closed

https://github.com/nervosnetwork/tentacle/blob/master/yamux/src/stream.rs#L180-L190

接受pr吗?我晚点可以试试修一下。

@umiro
Copy link
Author

umiro commented Aug 30, 2022

看了下Spec和Go的实现,收到FIN后需要再发一个FIN回去,那应该在这里将Ok(0)传播出poll_read就行了。

Err(io::ErrorKind::UnexpectedEof.into())

@driftluo
Copy link
Collaborator

driftluo commented Aug 30, 2022

或许可以在这里把状态切换到Closed?
https://github.com/nervosnetwork/tentacle/blob/master/yamux/src/stream.rs#L180-L190

这个是错的,yamux 有半关状态,直接切换是不行的

接受pr吗?我晚点可以试试修一下。

当然接受,如果有兴趣的话可以尝试一下,需要带上一个测试用例,类似这个

fn test_drop_with_state_reset() {

看了下Spec和Go的实现,收到FIN后需要再发一个FIN回去,那应该在这里将Ok(0)传播出poll_read就行了。

对,修法很简单,将这个函数拆开,在 RemoteClosing 的分支直接返回 Poll(Ok(()) 就可以了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants