/// <summary> /// Accepts the call back for asynch function /// </summary> /// <param name="result"></param> private void AcceptCallBack(IAsyncResult result) { SocketState sockState = new SocketState(); try { Socket s = (Socket)result.AsyncState; sockState.sock = s.EndAccept(result); sockState.buffer = new byte[BUFFER_SIZE]; lock (SocketsList) { SocketsList.Add(sockState); } sockState.sock.BeginReceive(sockState.buffer, 0, sockState.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), sockState); sock.BeginAccept(new AsyncCallback(AcceptCallBack), result.AsyncState); } catch (Exception e) { //KillConnection(conn); formTextBox.Text = "Killed a socket in call back " + e.Message; } }
/// <summary> /// Builds response message and prepares byte array /// </summary> /// <param name="count"> /// integer value that is a unique value to append to messages /// </param> /// <returns> /// formatted byte array /// </returns> public byte[] ResponseAsync(SocketState sockState, string serverIPAddress) { byte[] msgByte = null; msgArray[0] = "RSP"; msgArray[1] = sockState.stpWatch.ElapsedMilliseconds.ToString(); msgArray[6] = sockState.sock.RemoteEndPoint.AddressFamily.ToString(); msgArray[7] = "2605"; msgArray[8] = sockState.sock.Handle.ToString(); msgArray[9] = serverIPAddress; msgArray[11] = "OWServ " + sockState.countNumber.ToString(); //msgArray[0] = "RSP"; //msgArray[1] = msTimeStamp; //msgArray[6] = foreignHostIP; //msgArray[7] = "2605"; //msgArray[8] = serverSocketNumber; //msgArray[9] = serverIPAddress; //msgArray[11] = "OW " + count.ToString(); string message = String.Empty; //foreach (string s in msgArray) //{ // if (!s.Equals("")) // { // message += s + "|"; // } //} message = string.Join("|", msgArray); msgByte = System.Text.Encoding.ASCII.GetBytes(message); //msgByte = SetMsgLength(msgByte); //return msgByte; return SetMsgLength(msgByte); }
///// <summary> ///// Converts the first 2 bits read into ///// short and sets the message size to be ///// pulled off of the socket. Otherwise ///// the full size bits haven't been read so it will ///// send back and read until full size has been ///// read off of the socket. (Shouldn't have to ///// handle that with the type of read that is being done, ///// but easier than tracking down error). ///// </summary> ///// <param name="result"> ///// IAsyncResult cast as a SocketState ///// </param> //private void ReadSize(IAsyncResult result) //{ // //SocketState sockState = (SocketState)result; // SocketState sockState = (SocketState)result.AsyncState; // int bytesRead = sockState.sock.EndReceive(result); // //switch (bytesRead) // //{ // // case 0: // // { // // // full 2 bits length hasn't been received yet // // sockState.sock.BeginReceive(sockState.buffer, sockState.offset, // // sockState.size, SocketFlags.None, new AsyncCallback(ReceiveCallBack), result.AsyncState); // // break; // // } // // case 1: // // { // // // 1 bit has been read off the buffer, need to get the other one // // sockState.offset++; // // sockState.sock.BeginReceive(sockState.buffer, sockState.offset, // // sockState.size, SocketFlags.None, new AsyncCallback(ReceiveCallBack), result.AsyncState); // // break; // // } // // case 2: // // { // // Caclulate the size of the message coming in // // Varaibles for size calculation // byte[] byteSize = new byte[LENGTH_BITS]; // // Get the size values out of current message // Array.Copy(sockState.buffer, sockState.offset, byteSize, 0, LENGTH_BITS); // // Reverse the bits if they aren't in proper order for proc // if (BitConverter.IsLittleEndian) // { // Array.Reverse(byteSize); // } // // Set the size variable // sockState.size = BitConverter.ToInt16(byteSize, 0); // // Set the offset to begin read after size bytes // sockState.offset = LENGTH_BITS; // // send back to call back to receive the message // sockState.sock.BeginReceive(sockState.buffer, sockState.offset, sockState.size, // SocketFlags.None, new AsyncCallback(ReceiveCallBack), result.AsyncState); // // break; // //} // //} //} ///// <summary> ///// Reads the message from the socket. ///// If the full message hasn't been receieved it ///// will send back to the ReceiveCallBack function ///// and wait until the whole message has been yanked out of the ///// socket. If whole message hasn't been recieved the SocketState ///// offset value will be updated to the latest position in the ///// sockState object. ///// </summary> ///// <param name="result"></param> //private void ReadMessage(IAsyncResult result) //{ // //SocketState sockState = (SocketState)result; // SocketState sockState = (SocketState)result.AsyncState; // int bytesRead = sockState.sock.EndReceive(result); // if (bytesRead == sockState.size) // { // responseNumber++; // sockState.countNumber = responseNumber; // SendReply(sockState); // } // else // { // // whole message not received yet // sockState.sock.BeginReceive(sockState.buffer, sockState.offset, // sockState.size, SocketFlags.None, new AsyncCallback(ReceiveCallBack), result.AsyncState); // } //} /// <summary> /// build resposne and send it back call the send /// call back function to complete the send. /// The function assumes that the SocketState.proccesedBuffer /// contains the whole message to be processed and sent back /// to the client. /// </summary> /// <param name="sockState"> /// SocketState object. /// </param> private void SendReply(SocketState sockState) { // TODO: Format message then begin sending through SendCallBack. // Must build response then send the message through to the client. //byte[] choppedBuffer = new byte[sockState.size]; //byte[] processedBuffer; //Array.Copy(sockState.buffer, sockState.offset, choppedBuffer, 0, sockState.size); //ResponseBuilder rb = new ResponseBuilder(Encoding.ASCII.GetString(choppedBuffer)); //sockState.processedBuffer = rb.ResponseAsync(sockState, localServerIP); //sockState.processedSize = sockState.processedBuffer.Length; //sockState.sock.BeginSend(sockState.processedBuffer, 0, sockState.processedSize, // SocketFlags.None, new AsyncCallback(SendCallBack), sockState); }
/// <summary> /// Clears the connection to the current SocketState /// object from the SocketsList list /// </summary> /// <param name="sockState"> /// SocketState object to remove from the Sockets list /// </param> private void KillConnection(SocketState sockState) { sockState.sock.Close(); lock (SocketsList) { SocketsList.Remove(sockState); } }
/// <summary> /// processes the received message and carries out logic /// to resend the response back to the client /// </summary> /// <param name="choppedBuffer"> /// The received buffer chopped down to /// the size of actual bytes received instead of full /// 256 size array /// </param> /// <param name="sockState"> /// SocketState class object containing the /// values that are passed around for the message /// </param> private void SendFunction(byte[] choppedBuffer, SocketState sockState) { //byte[] processedBuffer = new byte[MAX_MSG_SIZE]; byte[] processedBuffer; // Process the incoming message and prepares it for response sockState.countNumber++; try { ResponseBuilder rb = new ResponseBuilder(System.Text.Encoding.ASCII.GetString(choppedBuffer)); processedBuffer = rb.Response(sockState.countNumber, sockState.stpWatch.ElapsedMilliseconds.ToString(), sockState.sock.RemoteEndPoint.AddressFamily.ToString(), sockState.sock.Handle.ToString(), localServerIP); lock (sendLock) { // Send message back to the client sockState.sock.Send(processedBuffer); } } catch (Exception e) { e.ToString(); } }
/// <summary> /// Accepts incoming connections and sets /// the socket to listen. Spawns a new thread and /// sends that to the connection handler function. /// </summary> private void AcceptConnections() { Socket socket = null; //do while (true) { // Accepts a connection on socket try { socket = sock.Accept(); } catch (Exception) { } SocketState sockState = new SocketState(); sockState.sock = socket; sockState.stpWatch.Start(); // Spawns thread and starts ConnectionHandler function sockState.thread = new Thread(delegate() { ConnectionHandler(sockState); }); sockState.thread.IsBackground = true; sockState.thread.Start(); //sockState.thread.Start(sockState); } //while (socket.Connected); }
/// <summary> /// Handles the connection input for recieving data /// from the client. /// </summary> /// <param name="value"> /// Takes a SocketState object that has a socket and thread /// assigned to it. /// </param> public void ConnectionHandler(SocketState sockState) { // Incoming buffer byte array byte[] buffer = new byte[BUFFER_SIZE]; // Message length byte array, stripped out of buffer byte[] byteSize = new byte[LENGTH_BITS]; // bytes received last read int bytesRead = 0; int messageCount = 0; try { //while (messageCount < MAX_MESSAGES) //while (true) while (sockState.sock.Connected) { // Current message receive byte[] messageBuffer = null; int offSet = 0; int size = 0; lock (receiveLock) { bytesRead = sockState.sock.Receive(buffer, offSet, LENGTH_BITS, SocketFlags.None); } // Get the size values out of current message Array.Copy(buffer, offSet, byteSize, 0, LENGTH_BITS); // Reverse the bits if they aren't in proper order for proc if (BitConverter.IsLittleEndian) { Array.Reverse(byteSize); } // Set the size variable size = BitConverter.ToInt16(byteSize, 0); // Set offSet variable offSet += LENGTH_BITS; lock (messageLock) { // Read next message out of buffer bytesRead = sockState.sock.Receive(buffer, offSet, size, SocketFlags.None); } // Set messageBuffer to new byte[] with size index messageBuffer = new byte[size]; // Copy message to messageBuffer Array.Copy(buffer, offSet, messageBuffer, 0, size); // Send message off, exit do while Thread senderThread = new Thread(delegate() { SendFunction(messageBuffer, sockState); }); senderThread.Start(); // Increment the message count messageCount++; # region NonMessageReceive //lock (receiveLock) //{ //// get whole message from client before moving on //do //{ // bytesRead = sockState.sock.Receive(buffer); // // if haven't received msg length, skip // if (bytesRead != 0) // { // Array.Copy(buffer, byteSize, 2); // // Swap to proper endian for machine // // Don't foget to optimize this back to try to save time! // if (BitConverter.IsLittleEndian) // { // Array.Reverse(byteSize); // } // short convertedValue = BitConverter.ToInt16(byteSize, 0); // //IPAddress.NetworkToHostOrder(convertedValue); // // Set msgSize to actual message size received so far // msgSize = BitConverter.ToInt16(byteSize, 0); // } //} //while (msgSize < buffer.Length); //// Truncate message so not to send too much data back. //choppedBuffer = new byte[bytesRead]; //Array.Copy(buffer, choppedBuffer, bytesRead); //// Reset counter values for next thread //bytesRead = 0; //msgSize = 0; //} //// spawn a new sender thread to handle sending messages //Thread senderThread = new Thread(delegate() //{ // SendFunction(choppedBuffer, sockState); //}); //senderThread.Start(); #endregion } } catch (Exception e) { e.Message.ToString(); } sockState.sock.Close(); //System.Windows.Forms.MessageBox.Show("Finished closed socket\r\n returned: " + sockState.countNumber + " Messages"); }