Esempio n. 1
0
        private void AcceptCallback(IAsyncResult ar)
        {
            Socket handlerSocket = null;

            try
            {
                //喚醒多個執行緒,讓進入Waitting回到Running狀態。
                // Signal the main thread to continue.
                SignalEvent.Set();

                //AsyncState 取得符合或包含非同步作業資訊的使用者定義的物件
                // Get the socket that handles the client request.
                Socket listener = (Socket)ar.AsyncState;  // 取得主要的socket, 其中包含使用者定義的物件及handles the client request
                //將主要正在 listening(正在連入的client Socket)轉交給另一個臨時的handlerSocket變數,並且結束接受此一客戶端的連線

                handlerSocket = listener.EndAccept(ar);
                //取得遠端節點的EndPoint handler.RemoteEndPoint.ToString().Split(':')[0]

                //SocketInformLog("A client has connected. client ip : " + handlerSocket.RemoteEP.ToString().Split(':')[0] + ",  Client Socket HashCode = " + handlerSocket.GetHashCode() + Environment.NewLine);

                gClientSocketList.Add(handlerSocket);
                // Create the state object.
                SocketStateObj state = new SocketStateObj();
                state.workSocket = handlerSocket;

                // 假設已連線的客戶端要傳送資料時,所指定的回呼函式-ReadCallback,這也是C#中的delagate型別
                // 定義當Socket 接收到資料時要交給哪一個函數處理,這裡定義了BeginReceive()
                // 參數第一個為存放的位置,為byte[],傳入的資料會置於此陣列中;第二參數為啟始位置、第三參數為一次接收的最大長度;
                // 第四為封包的旗標,例如標記為"廣播封包"之類,
                // 第五參數為開始接受資料時叫用的回呼函式,用AsyncCallback實體化指定ReadCallback為回呼函式,所以當客戶端將資料傳進來時,ReadCallback函式會被叫用;
                // 第六為狀態的參數,這個是用戶自訂,當回呼函式ReadCallback被叫用 時,此參數的值會被傳遞到ReadCallback,其中包含Socket,但是回呼函式仍會曉得是哪一個Socket在傳送資料。
                handlerSocket.BeginReceive(state.buffer, 0, SocketStateObj.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
            }
            catch (Exception e)
            {
                FireExceptionEvent(LEVSocketExceptionType.ConnectException, handlerSocket,
                                   "[AcceptCallback] An error occurred when attempting to access the socket or to receive data from a connected Socket." + Environment.NewLine + e);
            }
        }
Esempio n. 2
0
        private void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;

            //重新取回 state object
            // Retrieve the state object and the handler socket from the asynchronous state object.
            SocketStateObj state   = (SocketStateObj)ar.AsyncState;
            Socket         handler = state.workSocket;

            try
            {
                //SocketInformLog("Client is waitting and begining to receive data. client ip : " + handler.RemoteEndPoint.ToString().Split(':')[0] + ",  Client Socket HashCode = " + handler.GetHashCode() + Environment.NewLine);

                //叫用 EndReceive 完成指定的非同步接收作業, 參數asyn (ar) 識別要完成的非同步接收作業,並要從其中擷取最終結果。
                // Read data from the client socket.
                int bytesRead = handler.EndReceive(ar);
                //SocketInformLog("ReadCallback; byteRead = " + bytesRead);

                if (bytesRead > 0)
                {
                    #region msdn code
                    // There  might be more data, so store the data received so far.
                    //state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    //state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));

                    byte[] currentRead = new byte[bytesRead];
                    Array.Copy(state.buffer, currentRead, bytesRead);
                    state.listBuffer.AddRange(currentRead);
                    //FireReceivingEvent(SocketReceivingTyp.Fragment, handler, currentRead);

                    //content = state.sb.ToString();
                    //content = Encoding.UTF8.GetString(state.buffer, 0, bytesRead);

                    //only for compare, so use Encoding.ASCII
                    content = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
                    //SocketInformLog("Client is receiving data. client ip : " + handler.RemoteEndPoint.ToString().Split(':')[0] + ",  Client Socket HashCode = " + handler.GetHashCode() + Environment.NewLine);
                    //SocketInformLog("ReadCallback; content = " + content + Environment.NewLine);

                    // Check for end-of-file tag. If it is not there, read more data.
                    //if(LEVSocketUtilities.ByteArrayIndexOf(currentRead, 0, gOldVer_EOF_TokenBArray) > -1)
                    //if (content.IndexOf("<EOF>") > -1)
                    if (content.IndexOf(_OldVer_EOF_Token) > -1)
                    {
                        // All the data has been read from the
                        // client. Display it on the console.
                        //Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", content.Length, content);
                        // Echo the data back to the client.
                        //Send(handler, content);
                        byte[] packet = state.listBuffer.ToArray <byte>();
                        int    idx    = LEVSocketUtilities.ByteArrayIndexOf(packet, Encoding.ASCII.GetBytes(_OldVer_EOF_Token));
                        if (idx > -1)
                        {
                            byte[] cpy = new byte[idx];
                            Array.Copy(packet, cpy, idx);
                            FireReceivingEvent(SocketReceivingTyp.OldVerWholePacket, handler, cpy);
                        }
                        //SocketInformLog("ReadCallback; Get <EOF> and Send back to client." + Environment.NewLine);
                        //Send_PreviousVer(handler, "get Data finish");
                        state.listBuffer.Clear();
                        //state.sb.Clear();
                    }
                    else if (LEVSocketUtilities.ByteArrayIndexOf(currentRead, SocketCmdToken._packetDataEOF_.ToString()) > -1)
                    {
                        byte[] packet = state.listBuffer.ToArray <byte>();
                        int    idx    = LEVSocketUtilities.ByteArrayIndexOf(packet, SocketCmdToken._packetDataEOF_.ToString());
                        if (idx > -1)
                        {
                            byte[] cpy = new byte[idx];
                            Array.Copy(packet, cpy, idx);
                            FireReceivingEvent(SocketReceivingTyp.WholePacket, handler, cpy);
                        }
                        //FireReceivingEvent(SocketReceivingTyp.WholePacket, handler, state.listBuffer.ToArray<byte>());
                        state.listBuffer.Clear();
                    }
                    else
                    {
                        //SocketInformLog("ReadCallback; Not all data received. Get more." + Environment.NewLine);
                        // Not all data received. Get more.
                    }
                    handler.BeginReceive(state.buffer, 0, SocketStateObj.BufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), state);
                    #endregion

                    #region modify code
                    // All data received. Get next message.
                    // Not all data received. Get more.
                    //handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);        //new

                    //// There  might be more data, so store the data received so far.
                    ////state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
                    //state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));


                    //// Check for end-of-file tag. If it is not there, read more data.
                    //content = state.sb.ToString();

                    //////////////////////////////

                    //if (content.IndexOf("<EOF>") > -1)
                    //{
                    //    //// Reply to the client.
                    //    //Send(handler, resultData);

                    //    // All data received. Get next message.
                    //    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);        //new

                    //}
                    //else
                    //{
                    //    // Not all data received. Get more.
                    //    handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                    //}
                    #endregion
                }
            }
            catch (SocketException e)
            {
                /////////////////////////////////////////////////////////////
                //if (ex.ErrorCode == 10054 || ex.ErrorCode == 10053)
                //{
                //    log.Write(client_ip + " has left");
                //    LogHelper.WriteServerDataLog(LogHelper.MsgType.Normal, LogHelper.Action.ClientLefted,
                //            client_ip, "Client has left");
                //}
                //else
                //{
                //    //Console.WriteLine(ex);
                //    log.Write("ReadCallBack1: " + ex.Message);  //2013/8/22: Log exception message
                //    LogHelper.WriteServerDataLog(LogHelper.MsgType.Exception, LogHelper.Action.ServerMessages,
                //            "-", "ReadCallBack1: " + ex.Message);
                //}

                //SocketInformLog("[SocketException][ReadCallback] An error occurred when attempting to access the socket or to receive data from a connected Socket. ==> " + e + Environment.NewLine);
                //throw new Exception("[SocketException] An error occurred when attempting to access the socket or to receive data from a connected Socket. ==> " + e);
                //SocketInformLog("handlerSocket Close. HashCode = " + handler.GetHashCode() + Environment.NewLine);
                FireExceptionEvent(LEVSocketExceptionType.DisConnectException, handler, "[SocketException][ReadCallback] An error occurred when attempting to access the socket or to receive data from a connected Socket." + Environment.NewLine + e);
                closeClientSocket(handler, true, false);
                FireSocketMsgEvent(LEVSocketEventType.ClientDisconnect, handler, "Client is going to be disconnected.");
            }
            catch (Exception e)
            {
                //SocketInformLog("[Exception][ReadCallback] An error occurred when attempting to access the socket or to receive data from a connected Socket. ==> " + e + Environment.NewLine);
                FireExceptionEvent(LEVSocketExceptionType.DisConnectException, handler, "[Exception][ReadCallback] An error occurred when attempting to access the socket or to receive data from a connected Socket." + Environment.NewLine + e);
                //throw new Exception("[Exception] An error occurred when attempting to access the socket or to receive data from a connected Socket. ==> " + e);
                //log.Write("ReadCallBack2: " + e.Message);   //2013/8/22: Log exception message
                //LogHelper.WriteServerDataLog(LogHelper.MsgType.Exception, LogHelper.Action.ServerMessages,
                //        "-", "ReadCallBack2: " + e.Message);
            }
        }