1. There is WinAPI , there is a Berkeley sockets implementation in it, in particular, the send() function, which returns the number of bytes sent.
  2. In .NET there is a wrapper System.Net.Sockets.Socket , in it the Socket.Send() method, which calls the native send() and also returns this number .
  3. And in .NET there is System.Net.Sockets.NetworkStream , it is used in TcpClient and therefore in TcpListener . In this NetworkStream there is a NetworkStream.Write() method, which is a wrapper for Socket.Send() . And this NetworkStream.Write() does not return a number, but returns void .

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?

  • So nothing seems to be lost - there is even a comment - there is a socket in the blocking mode, if not all bytes are written - do you catch an exception, no? - isnullxbh
  • @isnullxbh And in which case they may not all be recorded? Because of which? It depends on how I should handle this exception - reconnect to the server or just try again. - KG
  • I think that you yourself can easily deal with this - look at what types of exceptions are caught by the catch: the socket is closed, the buffer becomes null , the stream becomes read- only, and so on. - isnullxbh
  • @isnullxbh code above seen? ANY are intercepted. - KG
  • Seen . Now offer to review you. - isnullxbh

1 answer 1

Socket.Send specifies a common interface for different types of sockets, both requiring a connection (for example, TCP), and not requiring a connection to be established (UDP). In blocking mode, when establishing a connection, all data will be sent, i.e. the previously known number of bytes will be returned, or an exception will be generated, and then there can be no question of the return value at all. In non-blocking mode, Send can return a smaller number of bytes than is actually indicated by the argument.

NetworkStream.Write sends data exclusively in blocking mode. Therefore, either all data will be transferred, or an exception will be raised. As previously mentioned. So There is no special point in duplicating a known number of bytes in return.

  • Thank you for reminding us about UDP, but what about the exception in the blocking mode, you do not know in which case it can be thrown out? Loss of network, firewall, driver problems or what? I just need to know how to handle it, what to write in catch , roughly speaking. Namely, I need to know if my application should, in the case of an exception, simply repeat the call to NetworkStream.Write or it should re-call Connect , because the connection is broken. - KG
  • @KG, show your code. - isnullxbh