Socket输入流如何检测EOF

Socket输入流如何检测EOF

结论:客户端Sockt输入流,无法获取服务器端输出流的EOF。
在JAVA环境下的解释
对于InputStream的 read(b, off, len) 方法 public int read(byte[] b, int off, int len) throws IOException,Javadoc的说明为:
If len is zero, then no bytes are read and 0 is returned; otherwise, there is an attempt to read at least one byte. If no byte is available because the stream is at end of file, the value -1 is returned; otherwise, at least one byte is read and stored into b.
The default implementation of this method blocks until the requested amount of input data len has been read, end of file is detected, or an exception is thrown.
那么对于服务端Socket的输入流来说,什么是 end of file - EOF?首先说明一点,没有所谓的标识字符是EOF,对于字节流来说,从0~255的每个字节都是正常的数据,EOF只是输入流的一种状态。
当Socket客户端关闭的时候,服务端输入流在读完所有数据之后就会检测到EOF,然后服务端输入流返回-1。如果客户端Socket没有关闭,并且没有数据可读取的情况下,read方法会阻塞,等待有数据可读。如果设置了SoTimeout,那么直到超时抛出异常,如果没有设置超时,那么会一直等待数据到达。
通过测试,客户端关闭Socket之后,服务端还可以重复读取,每次都返回-1。

在wxWidgets下是如何呢?
结论和java环境下是一样的,无法得到EOF。
看下面代码:

bool wxInputStream::Eof() const
{
    // the only way the base class can know we're at EOF is when we'd already
    // tried to read beyond it in which case last error is set accordingly
    return GetLastError() == wxSTREAM_EOF;
}

试图通过stream的 EOF 告知客户端当前文件传输完毕,这是不可能的事情。EOF = end of file。对于客户端是没有任何意义的,TCP不可能传输该标记。
下面代码可以收到EOF,是为什么?

    // If we don't receive anything for 10 seconds, assume a timeout
Socket->SetTimeout(10);

// Wait for some data to come in, or for an error and block on the socket calls
//Socket->SetFlags(wxSOCKET_WAITALL | wxSOCKET_BLOCK);
Socket->SetFlags(wxSOCKET_WAITALL);

// Output to the specified file
wxFileOutputStream FileOutputStream(Filename);
// Stream data in from the socket
wxSocketInputStream SocketInputStream(*Socket);
// The zlib decompression will decompress data from the socket stream
wxZlibInputStream ZlibInputStream(SocketInputStream);
// Write to the file stream the results of reading from the zlib input stream
FileOutputStream.Write(ZlibInputStream);
if(ZlibInputStream.Eof()){
    wxLogMessage("File gets EOF.");
}else{
    wxLogMessage("File gets not EOF.");
}
这个收到的EOF实际是timeout异常,不是服务器端发过来的EOF,在实际运行中,10秒后可以收到EOF,或者服务器关闭了联机也可以收到EOF。
发布了17 篇原创文章 · 获赞 2 · 访问量 1925

猜你喜欢

转载自blog.csdn.net/qq_23313467/article/details/104243860
今日推荐