Sign in to follow this  
RockySabre

Sockets or Threading Problem ?

Recommended Posts

RockySabre    122
hey, i am developing using c# a network application. In the application there is file transfer using multiple threads from different users. Where each thread has a socket that is transfering part of the file. Every socket wait a certain period of time for packet to be received. This period was set to 10. When i connect to one source with 20 connections(threads) for example, and i receiving data from him. I observe that the connections are disconnected gradually with time. I debugged the code, i found that a socket in a thread waited for the packet to come so it can receive it till timeout(10 seconds passed), so it is assumed that the sender is disconnected. I increased the timeout to 100 milliseconds. I observed that the connections disconnects more slowly, but the problem is still available. My question is what should i do to detect the state of the otherside's socket so i can take the decision to disconnect from it? and what should be the length of the timeout period ? any help will be appreciated, thnx.

Share this post


Link to post
Share on other sites
RockySabre    122
Thnx for response. well, i understand that blocking Socket.Connect() doesnt return till it connects or fails. Non-Blocking Socket.Connect() returns, and when it succeeds to connect it triggers an event. Well, in this application i dont use Socket.receivetimeout to set the time out. I have a loop that check Socket.available to know if their is data to receive or it will count till the timeout.

int n = 0;
while(true)
{
if(socket.available>0)
{
socket.receive(bytes);
break;
}
else
{
if(n == timeout)
{
socket.close();
}
n++;
Thread.Sleep(1);
}
}

Can u explain more to me what blocking and non-blocking has to do with my problem ?

Share this post


Link to post
Share on other sites
Antheus    2409
Is this TCP?

TCP has timeout of (forgotten the number), I think, 30 seconds or so. Or perhaps this isn't the timeout I'm thinking about.

If this is network ack timeout, then transferring over internet with 100ms timeout requirement will cause disconnects, especially without some reliable connection.

if this is UDP, then the same rule applies - 100 ms simply isn't enough. 2 seconds may be too short.

Bottom line is - you cannot detect the state of remote socket. You also do not disconnect it, unless you want to disconnect the client for application triggered reason (client logs out, has transferred all files, etc.).

TCP takes care of everything. If something happens, errors, un-acked packet for 30 seconds, network error, etc, your API will notify you of that. But beyond that, you don't trigger timeouts OR disconnects.

The average ping time for internet connections should be considered at some 250ms.

Share this post


Link to post
Share on other sites
RockySabre    122
i am using TCP, i didnt mean above 100 milliseconds sorry, i meant 100 seconds. Well should i make the thread wait forever for the packet to be received ? and another question, does the increasing in the number of these threads increases time needed for transmission significantly ? any help will be appreciated,thnx.

Share this post


Link to post
Share on other sites
Antheus    2409
You don't wait for data to be received. TCP guarantees delivery, or it reports an error after any part of data hasn't been acknowledged.

That's the whole point of TCP. With UDP you do need to implement acks and so on.

If you're sending to a slow connection, you might need to implement some minimal form of throttling, since sending too much data at one (megabytes per connection per second to dial-up ) can probably stress the network implementation. But even witthout it, TCP provides throttling.

If you're not receiving an answer, then the problem is with your other end that's not responding properly and doesn't send data back. But connection is alive nonetheless.

You general loop will look something like this:

either open or accept socket
while ( active )
{
receive some data.
append received data to buffer.
if whole message/packet/data unit is in buffer {
handle what is in buffer.
generate the response.
}
if any data is to be sent {
send it;
}
}
close socket.



Active flag will be set by application when it's done with the connection.

Last time I did some threading tests, each server and client handled some 200 threads (although single UDP socket) without any problem. The only problems came from non-thread related problems, but throughput was reduced by about 30%.

Share this post


Link to post
Share on other sites
RockySabre    122
Still i didnt get it. Do you mean if a connection is open, if the otherside crashed there is no way to know and close it? and the questions remain : should i make the thread wait forever for the packet to be received ? and another question, does the increasing in the number of these threads increases time needed for transmission significantly ? any help will be appreciated,thnx.

Share this post


Link to post
Share on other sites
Imgelling    222
How I handle ungracefull disconnects is in my receive method..

bytes_received = Socket.Receive(blah)
if (bytes_received== 0) client disconnected;
else
process data

*** Warning ***
The following may or may not be the best way, but it fits my needs (for now)
*** Warning ***

I check my socket lists with Poll in its own thread, if a client disconnects ungracefully, Poll will say that socket has data to read, but it wont have data when you receive on that socket, so my server disconnects that socket.

Share this post


Link to post
Share on other sites
RockySabre    122
thnx for your response. are you sure this is really working ? how would Poll function return that there is data to be received and there is nothing ? i hope you are right. Anyway, does the increasing in the number of these threads increases time needed for transmission significantly ?

Share this post


Link to post
Share on other sites
Imgelling    222
Oops, first let me fix an error, I use Select, not poll. Sorry.

I only have one thread for select, and one for the receive method, if you would like, I can email you the server/client in a rar so you can have a look at the code. Its not very pretty or documented, but should be easy to understand.

As for time needed to transfer, my server/client sends instantaneously. But, I have max users set to 4 (can be changed by changing the MAX_USERS) and I only have one computer so I run the server and 4 clients on one machine (meaning no internet lag). I have not tested it over the internet.

Share this post


Link to post
Share on other sites
RockySabre    122
actually, i dont know what u mean by select, explain more please. send your code if you have time. kimocono1986@hotmail.com

[Edited by - RockySabre on May 6, 2007 5:07:49 PM]

Share this post


Link to post
Share on other sites
Thunder Sky    144
I've worked a bit with WinSock a while ago. That was in C++, Im not sure how similar it is to C#. Select() takes a pointer to some struct (I believe) and a socket as its arguments and fills the struct with information about the sockets current state (if it has data waiting to be read etc). It is a blocking function and will not return until the socket is in a state other than "idle". Hope that helped, was a while back so Im not sure how acurate this is (and I never acctually used select, I went with nonblocking recvs).

I have a question of my own; why do people want to use several threads and sockets to send a single file? granted, sending too big packages might not be good but couldnt you just send a small one (or rather one with "apropiet" size), wait, and then send another one. I havnt bothered to realy look into it, but it seems that bitTorrent clients use this multiple tread/socket aproach. Why?

cheers
Thunder Sky

Share this post


Link to post
Share on other sites
RockySabre    122
well you use multiple sockets/threads so you can download different parts of the file from different sources at the same time. My problem is when there are alot of threads transfering data, will this affect the speed of sending and receiving the packets a big deal ? and if there another way to know that the remote socket is disconnected other than Socket.Select(...) i wanna know it also. Any help will be appreciated, thnx.

Share this post


Link to post
Share on other sites
Imgelling    222
Sent the server and client source in a 37k rar. You can have the server running and up to 4(can be changed) client programs running. If you open a 5th client, it will receive a "server full message"

If you close a client window without telling the server to disconnect you (bye typing "exit"), the server handles it properly.

As for a little help on Select, this link would explain it better than me.

http://msdn2.microsoft.com/en-us/library/system.net.sockets.socket.select.aspx

Share this post


Link to post
Share on other sites
Antheus    2409
Quote:
I have a question of my own; why do people want to use several threads and sockets to send a single file? granted, sending too big packages might not be good but couldnt you just send a small one (or rather one with "apropiet" size), wait, and then send another one. I havnt bothered to realy look into it, but it seems that bitTorrent clients use this multiple tread/socket aproach. Why?


Torrents open many connections.

Single threaded aproach for high traffic applications breaks down (stalls) quickly.

Threading allows for much better load balancing.

Keep in mind, torrent doesn't send a single file, it sends hundreds of chunks to possibly hundreds of clients.

Share this post


Link to post
Share on other sites
Thunder Sky    144
I should have expained a bit more. Naturaly if you want to send/recv to/from several other clients you need more than one socket. What I ment was "why are several sockets used when sending to a single client". But I guess you kind of answered that: in case on socket breaks down the clients can continue exanging data without having to wait for the socket to be closed properly then connected again. right?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this