I'm creating a network protocol based on Tcp, and i am using berkeley socket via C#.
is the socket buffer gonna mixed up when two threads trying to send data via socket.send method at a time?
should i use lock for accessing one thread at a time?
According to MSDN, the Socket class is thread safe. So, that means you don't need to lock the send method and you can safely send and receive on different threads. But be aware that the order is not guaranteed, so the data won't be mixed if you send it all at a single call to the send method instead of chuncked calls.
In addition to that, I would recommend to lock and flush it just in case you don't want the server swapping the responses across multiple concurrent requests. But that doesn't seems to be this case.
Related
I have a WebSocket Server that uses the System.IO.Stream class to communicate (1 Stream per connection). The server needs to send and receive, (C# .NET 2.0) and the Stream object is created from the generated TcpClient when I accept a connection.
The desired setup is I have Stream.Read on one thread handling all the incoming messages. It's a loop where Stream.Read() is expected to block as messages come in.
On another thread, I need to occasionally send messages back to the client using Stream.Write().
My question is, would there ever be a race condition? Is it possible when I fire off a Stream.Write() while Stream.Read() is waiting/reading that I could muddle up the incoming read data? or is Stream smart enough to lock up the resources for me? Is there any case where having these two sitting on Read() and Write() at the same time could break things?
After some more research, it turns out it's a NetworkStream object. Which does indeed handle synchronous read/write without a race condition:
https://msdn.microsoft.com/en-us/library/system.net.sockets.networkstream(v=vs.110).aspx
Read and write operations can be performed simultaneously on an instance of the NetworkStream class without the need for synchronization. As long as there is one unique thread for the write operations and one unique thread for the read operations, there will be no cross-interference between read and write threads and no synchronization is required."
Here is my scenario:
Multiple sockets on one application
I want to receive and send on any number of these sockets
The only solution I have found so far to get around threading issues and bizzare exceptions is:
Each socket has it's own thread
Each socket has it's own concurrent queue which it constantly checks to see if it has a message to send
To send from a specific socket, regardless of thread, then you just add the message to the correct socket concurrent queue
However, this get's pretty costly. I am not a big fan of threading in general, and I have a niggly feeling there's a much better way. I am thinking about the poller - it allows you to receive from multiple sockets without needing to create a new thread per socket (as far as I'm aware). If this is right, is there no way to get it to send pending messages?
Otherwise, is multiple threads my only option? Thanks
When talking sockets programming in C# what does the term blocking mean?
I need to build a server component (possibly a Windows service) that will receive data, do some processing and return data back to the caller. The caller can wait for the reply but I need to ensure that multiple clients can call in at the same time.
If client 1 connects and I take say 10 seconds to process their request, will the socket be blocked for client 2 calling in 2 seconds later? Or will the service start processing a second request on a different thread?
In summary, my clients can wait for a response but I must be able to handle multiple requests simultaneously.
Blocking means that the call you make (send/ receive) does not return ('blocks') until the underlying socket operation has completed.
For read that means until some data has been received or the socket has been closed.
For write it means that all data in the buffer has been sent out.
For dealing with multiple clients start a new thread for each client/ give the work to a thread in a threadpool.
Connected TCP sockets can not be shared, so it must be one socket per client anyway.
This means you can't use the socket for anything else on the current executing thread.
It has nothing to do with szerver side.
It means the thread pauses whilst it waits for a response from the socket.
If you don't want it to pause, use the async methods.
Read more: http://www.developerfusion.com/article/28/introduction-to-tcpip/8/
A blocking call will hold the currently executing thread until the call completes.
For example, if you wish to read 10 bytes from a network stream call the Read method as follows
byte[] buf = new byte[10];
int bytesRead = stream.Read(buf, 0, buf.Length);
The currently executing thread will block on the Read call until 10 bytes has been read (or the ReadTimeout has expired).
There are Async variants of Read and Write to prevent blocking the current thread. These follow the standard APM pattern in .NET. The Async variants prevent you having to deal out a Thread (which will be blocked) to each client which increases you scalability.
Blocking operations are usually those that send or receive data and those that establish connections (i.e. listen for new clients or connect to other listeners).
To answer your question, blocking basically means that the control stays within a function or block of code (such as readfile() in c++) until it returns and does not move to the code following this code block.
This can be either in a Single threaded or a Multi-threaded context. Though having blocking calls in a single threaded code is basically recipe for disaster.
Solution:
To solve this in C#, you can simply use asynchronous methods for example BeginInvoke(), and EndInvoke() in the sockets context, that will not block your calls. This is called asynchronous programming method.
You can call BeginInvoke() and EndInvoke() either on a delegate or a control depending on which ASYNCHRONOUS method you follow to achieve this.
You can use the function Socket.Select()
Select(IList checkRead, IList checkWrite, IList checkError, int microSeconds)
to check multiple Sockets for both readability or writability. The advantage is that this is simple. It can be done from a single thread and you can specify how long you want to wait, either forever (-1 microseconds) or a specific duration. And you don't have to make your sockets asynchronous (i.e.: keep them blocking).
It also works for listening sockets. It will report writability. when there is a connection to accept. From experimenting, i can say that it also reports readability for graceful disconnects.
It's probably not as fast as asyncrhonous sockets. It's also not ideal for detecting errors. I haven't had much use for the third parameter, because it doesn't detect an ungraceful disconnect.
You should use one socket per thread. Blocking sockets (synchronous) wait for a response before returning. Non-blocking (asynchronous) can peek to see if any data received and return if no data there yet.
I would like to use the C# asynchronous io model for my socket. I have multiple
threads that need to send over the socket. What is the best way of handling this?
A pool of N sockets,with access controlled by lock? Or is asynch send thread-safe
for multiple threads accessing a single socket?
THanks!
Jacko
The async methods already create new threads to send the data. This will probably add unnecessary overhead to your application. If you already have multiple threads, you can create an IDispoable type of object to represent access to the socket and a manager which will control the checkin and checkout for the socket. The socket would checkin itself when the IDisposable dispose method is called. This way you can control what methods your threads can perform on the socket as well.
If the socket is already checked out by another thread, the manager would simply block until it's available.
using (SharedSocket socket = SocketManager.GetSocket())
{
//do things with socket
}
System.Threading.Semaphore is something that becomes handy in synchronizing and racing conditions
At the first look when using asynchronous methods on the socket level, there shouldn't be problems with sending and receiving data from the associated network stream, or 'directly' on the socket. But, you already probably know, there is.
The problem is particularly highlighted on the Windows Mobile platform and the Compact Framework.
I use asynchronous methods, BeginReceive and the callback function which performs ends a pending asynchronous read for the received data (EndReceive) from the async. result.
As i need to constantly receive data from the socket, there is a loop which waits for the data.
The problems begins when i want to send data. For that purposes before sending some data through the socket i'm "forcing" ends of asynchronous read with EndReceive. There is a great delay on that (sometimes you just can't wait for this timeout). Timeout is too long, and i need to immediately send the data. How? I don't want to close the socket and reconnect.
I use synchronous method Send for sending data (although the results are the same with async. methods BeginSend/EndSend). When sending is finished, i start to receive data again.
Resources that i know about:
stackoverflow.com...properly-handling-network-timeouts-on-windows-ce - comment about timeouts,
developerfusion.com...socket-programming-in-c-part-2/ - solution for simple client/server using asynchronous methods for receiving and synchronous method Send for sending data.
P.S.:I tried to send the data without ending asynchronous receive but then i got SocketException: A blocking operation is currently executing (ErrorCode: 10036).
Thanks in advance! I hope that i'm not alone in this 'one little problem'.. : )
Have you considered to use Poll (or Select for multiple sockets) static method instead of BeginReceive to check if there are data for read? In my opinion this is causing you the trouble.