Can anyone answer a question about Socket.OnDataRecieve()?
I have a question that's really bothered me ever since I started working with sockets and it's the big reason I always get stuck launching a thread to read over and over rather than taking advantage of Windows (in this case, C#.NET) events. Suppose I were to, say, send a long string (256 characters) over a socket. On the other side, what is the response? Does it launch the OnDataRecieved() handler 256 times? If so, do they run in sequence or parallel? It's pretty important that I be able to decode messages and send a response. Like I said, traditionally I've just launched a thread to keep reading and it's a kludge. It particularly interferes with trying to send back anything other than a request-response-request-response pattern. My concern, writing a game, is having 200+ threads running non-stop because everyone logged on had to have 1 for reading and 1 for writing on top of whatever the game's actually doing (AI, events, etc).
OnDataReceived is not a documented member of System.Net.Socket, so it's kind of hard to figure out how it's supposed to behave :-)
enum Bool { True, False, FileNotFound };
(Assuming TCP/IP)
Sockets recieve data in chunks, not single characters; so in your above example, the event for receive would be fired once most likely, with 256 bytes of data in the read buffer that you can read in as you please (you can read in single characters, or multiple bytes into a byte array). However, depending on the amount of data, and the state of the connection, a single send of data might not send all of it, and when receiving it might not receive all of it with one call. It is up to the application to manage this.
Sockets recieve data in chunks, not single characters; so in your above example, the event for receive would be fired once most likely, with 256 bytes of data in the read buffer that you can read in as you please (you can read in single characters, or multiple bytes into a byte array). However, depending on the amount of data, and the state of the connection, a single send of data might not send all of it, and when receiving it might not receive all of it with one call. It is up to the application to manage this.
I know I read it somewhere. They had a method for OnDataSent as well. Perhaps it was CSocket in MFC (really do overlap alot in my thought process). Tylon confirmed my suspicion, that it would theoretically be called after every read until I hit 256 bytes.
So looking over the MSDN docs for .NET's Socket class again, it looks like I still would have to have a thread do reading (blocking or async) and raise it's own event. That fits my purpose(s) a million times better, since I want to receive a predefined "instruction" object. Looks like I need not change what I was doing all along, thanks!
So looking over the MSDN docs for .NET's Socket class again, it looks like I still would have to have a thread do reading (blocking or async) and raise it's own event. That fits my purpose(s) a million times better, since I want to receive a predefined "instruction" object. Looks like I need not change what I was doing all along, thanks!
I've gotten to likin' the whole Asynch sockets...
I do this in my constructor:
Then, my "OnReceive" method:
Its very little overhead, if any, due to the fact its not in a tightly knit while loop.
I do this in my constructor:
public Connection(Socket m_TCPClient) { try { State = ConnectionState.Connecting; m_TCP = m_TCPClient; m_RemoteEndPoint = m_TCP.RemoteEndPoint; m_UDPPort = Convert.ToInt32(ConfigurationSettings.AppSettings["intUDPPort"]); receiveProc = new AsyncCallback(OnReceive); m_TCP.BeginReceive(received, 0, received.Length, SocketFlags.None, receiveProc, m_TCP); } catch(Exception ex) { Trace.WriteLine("Error creating Connection object: " + ex.Message); } }
Then, my "OnReceive" method:
public void OnReceive(IAsyncResult ar) { Socket so = (Socket)ar.AsyncState; int BytesRead = so.EndReceive(ar); if(BytesRead > 0) { QueuePacket objPacket = new QueuePacket(); objPacket.LoadFromRaw(received); if(objPacket.PacketHeader.Offset == 0 && objPacket.PacketHeader.PacketLength == objPacket.PacketHeader.TotalSize) { Trace.WriteLine(MessageQueue.TYPE + "-CCR-" + objPacket.PacketHeader.ObjectID.ToString()); MessageQueue.IncomingMessages.Add(new Message(objPacket)); } else { Trace.WriteLine(MessageQueue.TYPE + "-PFR-" + objPacket.PacketHeader.ObjectID.ToString()); MessageQueue.AddFragment(objPacket); } } received = new byte[QueuePacket.MAXPACKETLENGTH]; m_TCP.BeginReceive(received, 0, received.Length, SocketFlags.None, receiveProc, m_TCP); }
Its very little overhead, if any, due to the fact its not in a tightly knit while loop.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement