1
votes

I'm developing a server for mobile machines that implements a socket server to receive their connection, by using Visual Studio Express 2013.

It uses Net.Sockets.TcpListener.AcceptSocket to assign the connection to a Net.Sockets.Socket. It start a new Threading.Thread for each new socket created, with a while cycle to receive, parsing and write data to the socket. It uses the property x.Available to get the data count and reads that data with the x.Receive(buffer, datalen, Net.Sockets.SocketFlags.None). It parses the data received and create the answer. Finally it uses the x.Send(answerbuffer, answerdatalen, Net.Sockets.SocketFlags.None) to transmit the answer.

The code works correcty on receive and send the answer, but it is quite slow.

I put some check on the code to get the elapsed time on each operation of the code and I get that average values: - socket read and copy data from buffer to a list (of bytes): 100-200 ms - data parsing and creating of an answer buffer list (of bytes): 150-300 ms - converting buffer list (of bytes) to buffer array of bytes and socket send: 70-200 ms

Keeping in mind data receive for packet is about 150 byte length and data transmit is about 100 byte length, the timings for each execution part of the thread are quite high. So when the server receives more connections toghether, the answers slows down or stops for a while.

Does this method of using a Socket and a Thread for each connection on the server is bad? Do I make a search of some other class to manage the data streaming or thread parallel executions? Does visual studio express have some limitation on working with threads?

Thank you for the help. Matteo

1
If these are transient connections it's probably going to be significantly faster to use AcceptSocketAsync since that will use a thread pool.500 - Internal Server Error

1 Answers

1
votes

Does this method of using a Socket and a Thread for each connection on the server is bad?

Yes, very bad. Threads don't scale at all, and additionally: if you're using threads per socket, an accidental or malicious DDOS is virtually guaranteed.

You can just about get away with thread-per-socket at the client, if you're only connecting to a few sockets. At the server: that's just death.

Server socket IO is almost always done using async IO. This gets complicated really quickly, especially when talking about back-buffers etc, but : there's an entire new API available in modern .NET for this scenario: "pipelines" - that deals with all of the the threading, memory pooling, and back-buffer management for you. It really isn't going to work on Visual Studio 2013, though, so... update if possible? If that is of interest, I have a multi-part saga on using pipelines.

If that isn't possible, a good place to start might be something like SocketAsyncEventArgs, but again: this is a really really deep rabbit hole, and frankly it is mostly a solved problem. If you can switch to a pre-rolled implementation, I'd recommend it.