TcpClient.GetStream().Read() vs. TcpClient.Client.Receive() - c#

.NET allows two very similar ways to "read" from the network (assuming TCP connection):
1. TcpClient.GetStream().Read()
2. TcpClient.Client.Receive()
By looking at NetworkStream source code - it seems that it's an extra wrapper over the underlying socket, which eventually calls Socket methods.
Question: what's the benefit of using "indirect" NetworkStream variation (#1), instead of using direct wrapper provided by Socket implementation?
Thank you,
Boris.

There is, in fact, a pretty clear benefit of using the first option (TcpStream and not Socket). The benefit is that stream API is more flexible when different underlying implementations are needed at for the same program.
For example, a code which sometimes may use SSL and sometimes may not use it, can switch between SslStream and TcpStream with no changes to the calling code. This is something which is much harder to accomplish using only plain Socket API.

Nothing, really. It's just that sometimes it's more convenient to use a Stream.

To me, a successful Socket.Receive operation with zero bytes received tells you that connection is closed.

Related

Socket stop all blocking calls

I am working on a networking library. I have already implemented Socket wrappers for both UDP and TCP connections. Now there are some situations in which after already creating the wrapper I need to directly work on the underlying sockets. But how do I stop blocking read() calls in the wrapper while not dropping the connection/missing any messages?
Here are some of the things I have thought about:
Using DuplicateAndClose() which sounds like it does exactly what I want, preventing the first Socket instance from being used while providing me with a new one to work on and keeping the connection intact. But this seems to be a windows only solution.
Setting the read timeout to 1 and checking for a closed flag everywhere the socket is used. I do not like this solution as it feels kind of hacky and would require quite a bit of code changes.
Are there any alternatives I have missed?
Edit: Switching to non-blocking or async sockets is currently not possible for me. But as pointed out in the comments with async Sockets this is easy to solve (for anyone else facing this issue)

Socket GetSocketOption()/SetSocketOption with SendLowWater C#

I am having trouble in using the GetSocketOption() and SetSocketOption() method with SendLowWater in the socket class.
I tried using
byte[] values = new byte[100];
sock.GetSocketOption(System.Net.Sockets.SocketOptionLevel.Socket, System.Net.Sockets.SocketOptionName.SendLowWater, values);
I get the following exception at the function call: An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call
Does anyone know how to use GetSocketOption/SetSocketOption with SendLowWater?
Thank you,
kab
It seems to me that the error message is pretty self-explanatory: the "send low water" option is not supported on Windows.
Fortunately, you don't really need this option. It's used to control the behavior of the Winsock select() function, exposed in .NET as Socket.Select(), which is not needed nor desired for effective use of the .NET Socket class. Instead, you should use one of the asynchronous methods for using Socket.
My personal preference now that C# has the async/await feature is to wrap the Socket in a NetworkStream and use the Stream.ReadAsync() and Stream.WriteAsync() methods. Like the other asynchronous methods, these will use IOCP to handle the asynchronous behavior (the most efficient I/O model in Windows), but in a way that is much more convenient than the other two Socket-based asynchronous methods.
You don't.
SocketOptionName.SendLowWater corresponds to SO_SNDLOWAT (4099), which the MSDN documents as not supported:
A socket option from BSD UNIX included for backward compatibility.
This option sets the minimum number of bytes to process for socket
output operations.
This option is not supported by the Windows TCP/IP provider. If this
option is used on Windows Vista and later, the getsockopt and
setsockopt functions fail with WSAEINVAL. On earlier versions of
Windows, these functions fail with WSAENOPROTOOPT.
The Socket class is a low-level wrapper around the Winsock functions, so if something fails, you can generally find more detailed information by figuring out what native call your operation corresponds to (in this case setsockopt.

C# game client with asyncronous sockets

I'm developing a small online game in C#. Currently I am using simple sync TCP sockets. But now (because this is some kind of "learning project") I want to convert to asynchronous sockets. In the client I have the method: byte[] SendAndReceive(Opcode op, byte[] data).
But when I use async sockets this isn't possible anymore.
For example my MapManager class first checks if a map is locally in a folder (checksum) and if it isn't, the map will be downloaded from the server.
So my question:
Is there any good way to send some data and get the answer without saving the received data to some kind of buffer and polling till this buffer isn't null?
Check out IO Completion Ports and the SocketAsyncEventArgs that goes with it. It raises events when data has been transferred, but you still need a buffer. Just no polling. It's fast and pretty efficient.
http://www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod
and another example on MSDN
http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx
A code example of what you have would help, but I'd suggest using a new thread for each socket connection with a thread manager. Lmk if that makes sense or if that' applicable here. :)

Can I rely on DataAvailable for an SSL-wrapped networkstream?

I'm dealing with an application that does a lot of asynchronous reading. To improve performance, I'd like to directly do a synchronous call to Read from an SslStream provided that the call does not block.
The SslStream itself does not provide a DataAvailable property like the underlying NetworkStream does.
So, given that I know that it's a wrapped network stream being read, will the true in DataAvailable guarantee that the call to the SslStream won't cause a block?
Like this:
public void Read(NetworkStream netStream, SslStream sslStream)
{
// given that netStream is the inner stream of sslStream
if (netStream.DataAvailable)
{
// Will not block
sslStream.Read(...);
}
else
{
// Would block
sslStream.Read(...);
}
}
The SslStream is already authenticated and ready to go. I'm not sure if there are any additional overhead apart from the encrypting/decrypting. I assume the answer is reliant on if the SslStream requires a read of more than one byte from the underlying stream in order to read one encrypted byte.
No it doesn't guarantee that, because there are SSL Records at the next layer down, and you may not have received an entire one yet, and cryptologically speaking you can't do anything until you have it all, as you first have to check the MAc for integrity purposes.
But more to the point, I question the whole strategy. Just issue the reads as you need them in normal code: don't try to guess which mode will work best in each situation. The SSL overhead will probably swamp the sync/async difference, and the network bandwidth limitation will swamp them both.
It depends on the cipher in use- endpoints using RC4 or another stream cipher are more likely to be decryptable one byte at a time, but no guarantees. An endpoint configured for DES or other block ciphers will wait until a full block is available.
You could do some screwy stuff with a peekable intermediate buffering stream and try to make sure you've got a reasonable block size before making a blocking read, but that's nasty.
If you absolutely can't block, I'd stick to BeginRead and a completion delegate.

C#: SSL with SocketAsyncEventArgs?

I'm developing a socket server using C# .NET. I'm using the async model provided by the SocketAsyncEventArgs class, because it must be a high performance server to support many connections in short periods of time. Next, I want to secure the communication between
clients and server, and I think I could use SSL.
Is there any way of using SSL with the SocketAsyncEventArgs model? I know .NET has the SslStream class for SSL securing, but I need to use SocketAsyncEventArgs for high performance.
Is it possible to use SSL in an upper level, without implementing it in the server code?
Thanks in advance.
Not sure if anyone cares anymore since this is so old but I needed to do just that this week and could not find anything on the internet that met my needs. Maybe there is something new in the framework that does this that I was unable find... Regardless, I would post source code but since I wrote it for my company and they tend to frown on that, I'll just outline the approach I took:
Since SslStream takes a stream in the constructor, I implemented my own Stream subtype with an underlying MemoryStream for reads and another for writes. I also pass in the TcpClient to this object as well.
I used the TcpClient to do the handshake for setting up the SSL connection. After authenticating the server or client depending on how I am using it, I then use my two MemoryStreams for the SslStream read/writes.
So for Async writes, I first write my payload to the SslStream which populates my MemoryStream for writing with encrypted data. With the encrypted data from the MemoryStream, I populate the SocketAsyncEventArgs buffer and call the TcpClient SendAsync method. For reads, it's pretty much the opposite.
I can't say it particular excites me to move the data like that but as long as you don't let your MemoryBuffer objects get reallocated constantly, it's not a performance issue. At least this way, I can use just the framework and my own code without relying on third party software.
You can take third-party implementation of SSL/TLS protocol, such as our SecureBlackbox, and use it with any transport, including .NET Sockets in asynchronous mode. SSL server component of SecureBlackbox doesn't have it's own socket, instead it fires events, in whose handlers you write your socket-related code. This way you an plug any transport, even non-socket one.
I think I may have found a project that provides this.
https://sourceforge.net/projects/socketservers/
I'm still playing with it and am bumping into an issue loading the server certificate, however, looking through the source code it looks promising.
One aspect I'm unsure about is that it p/invokes to secur32.dll rather than being a pure c# implementation, so I'm not sure what the memory/performance impact of that is.
The details on the sourceforge project page are sparse as to what the goal of the project is.

Categories