protected override void OnConnect() { EODataChunk wrap = new EODataChunk(); StartDataReceive(wrap); m_packetProcessor = new ClientPacketProcessor(); //reset the packet processor to allow for new multis }
protected override void OnReceiveData(DataChunk state) { EODataChunk wrap = (EODataChunk)state; if (wrap.Data.Length == 0) { wrap.State = EODataChunk.DataReceiveState.NoData; } try { switch (wrap.State) { case EODataChunk.DataReceiveState.ReadLen1: { wrap.RawLength[0] = wrap.Data[0]; wrap.State = EODataChunk.DataReceiveState.ReadLen2; wrap.Data = new byte[EODataChunk.BUFFER_SIZE]; StartDataReceive(wrap); break; } case EODataChunk.DataReceiveState.ReadLen2: { wrap.RawLength[1] = wrap.Data[0]; wrap.State = EODataChunk.DataReceiveState.ReadData; wrap.Data = new byte[Packet.DecodeNumber(wrap.RawLength)]; StartDataReceive(wrap); break; } case EODataChunk.DataReceiveState.ReadData: { byte[] data = new byte[wrap.Data.Length]; Array.Copy(wrap.Data, data, data.Length); m_packetProcessor.Decode(ref data); //This block handles receipt of file data that is transferred to the client. //It should make file transfer nuances pretty transparent to the client. //The header for files stored in a Packet type is always as follows: FAMILY_INIT, ACTION_INIT, (InitReply) //A 3-byte offset is found throughout the code that handles creating these files. if (data[0] == 255 && data[1] == 255) //INIT_INIT packet! check to see if expecting a file or player list { Packet pkt = new Packet(data); byte reply = pkt.GetChar(); if (ExpectingFile) { int dataGrabbed = 0; //find first zero byte int pktOffset = 0; for (; pktOffset < data.Length; ++pktOffset) { if (data[pktOffset] == 0) { break; } } //continue receiving until we have grabbed enough data to fill the allocated packet buffer do { byte[] fileBuffer = new byte[pkt.Length - pktOffset]; int nextGrabbed = ReceiveRaw(ref fileBuffer); Array.Copy(fileBuffer, 0, data, dataGrabbed + 3, data.Length - (dataGrabbed + pktOffset)); dataGrabbed += nextGrabbed; } while (dataGrabbed < pkt.Length - pktOffset); if (pktOffset > 3) { data = data.SubArray(0, pkt.Length - (pktOffset - 3)); } //rewrite the InitReply with the correct value (retrieved with GetChar, server sends with GetByte for other reply types) data[2] = reply; } else if (ExpectingPlayerList) { //online list sends a char... rewrite it with a byte so it is parsed correctly. data[2] = reply; } } ThreadPool.QueueUserWorkItem(_handlePacket, new Packet(data)); EODataChunk newWrap = new EODataChunk(); StartDataReceive(newWrap); break; } default: { Console.WriteLine("ERROR: Invalid data wrapper state in _recvCB (should be ReadLen1, ReadLen2, or ReadData). Closing connection."); Disconnect(); break; } } } catch (SocketException se) { //in the process of disconnecting Console.WriteLine("There was a SocketException with SocketErrorCode {0} in _recvCB", se.SocketErrorCode); } }