- There is WinAPI , there is a Berkeley sockets implementation in it, in particular, the
send()function, which returns the number of bytes sent. - In .NET there is a wrapper
System.Net.Sockets.Socket, in it theSocket.Send()method, which calls the nativesend()and also returns this number . - And in .NET there is
System.Net.Sockets.NetworkStream, it is used inTcpClientand therefore inTcpListener. In thisNetworkStreamthere is aNetworkStream.Write()method, which is a wrapper forSocket.Send(). And thisNetworkStream.Write()does not return a number, but returnsvoid.
One would assume that an algorithm is implemented inside NetworkStream.Write , which calls Socket.Send several times, and thus ensures that all bytes are transmitted, in which case it should not return a number, since all bytes end up being written.
But we open the source code of the NetworkStream.Write method, and we see that this is not so:
/// <devdoc> /// <para> /// Writes data to the stream.. /// </para> /// </devdoc> public override void Write(byte[] buffer, int offset, int size) { #if DEBUG using (GlobalLog.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif if (m_CleanedUp){ throw new ObjectDisposedException(this.GetType().FullName); } // // parameter validation // if (buffer==null) { throw new ArgumentNullException("buffer"); } if (offset<0 || offset>buffer.Length) { throw new ArgumentOutOfRangeException("offset"); } if (size<0 || size>buffer.Length-offset) { throw new ArgumentOutOfRangeException("size"); } if (!CanWrite) { throw new InvalidOperationException(SR.GetString(SR.net_readonlystream)); } Socket chkStreamSocket = m_StreamSocket; if(chkStreamSocket == null) { throw new IOException(SR.GetString(SR.net_io_writefailure, SR.GetString(SR.net_io_connectionclosed))); } try { // // since the socket is in blocking mode this will always complete // after ALL the requested number of bytes was transferred // chkStreamSocket.Send(buffer, offset, size, SocketFlags.None); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, exception.Message), exception); } catch { // // some sort of error occured on the socket call, // set the SocketException as InnerException and throw // throw new IOException(SR.GetString(SR.net_io_writefailure, string.Empty), new Exception(SR.GetString(SR.net_nonClsCompliantException))); } #if DEBUG } #endif } What? This number is simply lost in NetworkStream.Write and in general it is not involved in any way.
Maybe it really doesn't make sense to check it and all bytes are always written successfully? But some people write that this is not always the case, and why is it then asked that Send returns a value if it is not needed?
So after all, can not all bytes be written to the stream? In which case?