Beispiel #1
0
 public int SendMsg(StateObject socObj)
 {
     return(Send(socObj.Soc, socObj.Data));
 }
Beispiel #2
0
 public virtual void ProcessMsg(StateObject socObj)
 {
     //need implementing
 }
Beispiel #3
0
        public void StartListening()
        {
            IPHostEntry ipHostInfo = new IPHostEntry();

            ipHostInfo.AddressList = new IPAddress[] { new IPAddress(new Byte[] { 127, 0, 0, 1 }) };
            IPAddress ipAddress = ipHostInfo.AddressList[0];

            IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, mPort);

            // Create a TCP/IP socket.
            mServerSoc = new Socket(AddressFamily.InterNetwork,
                                    SocketType.Stream, ProtocolType.Tcp);
            mServerSoc.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, (int)1);

            // Bind the socket to the local endpoint and
            // listen for incoming connections.
            try
            {
                mServerSoc.Bind(localEndPoint);
                mServerSoc.Listen(mClientSize);
                mServerStateObj        = new StateObject(mServerSoc, "");
                mServerStateObj.Key    = mKey;
                mServerStateObj.Status = SocHandlerStatus.LISTENING;

                if (mPort == 0)
                {
                    mPort = ((IPEndPoint)mServerSoc.LocalEndPoint).Port;
                }

                Logger.info(string.Format("Start Listening. port[{0}]", mPort));

                int waitCount = 0;

                // Start listening for connections.
                while (true)
                {
                    lock (mClientTableLock)
                    {
                        if (mHtClientTable.Count >= mClientSize)
                        {
                            if (mWaitCount > 0) //0인경우 무한반복허용
                            {
                                if (waitCount >= mWaitCount)
                                {
                                    Logger.info(string.Format("Wait 횟수 {0}회 초과.", waitCount));
                                    StopListening();
                                    break;
                                }
                                else
                                {
                                    waitCount++;
                                }
                            }
                            mServerStateObj.SocMessage = string.Format("Wait 허용접속자수 초과 {0} >= {1}", mHtClientTable.Count, mClientSize);
                            Logger.debug(mServerStateObj);
                            System.Threading.Thread.Sleep(SocConst.WAIT_MIL_SEC);
                            continue;
                        }
                    }

                    lock (mServerLock)
                    {
                        if (mServerStateObj.Status == SocHandlerStatus.STOP)
                        {
                            Logger.info("ServerSocket Stopped.");
                            return;
                        }
                    }

                    // Program is suspended while waiting for an incoming connection.
                    mServerStateObj.SocMessage = string.Format("Port[{0}] 접속대기...", mPort);
                    Logger.info(mServerStateObj);
                    OnSocStatusChangedOnInfo(new SocStatusEventArgs(mServerStateObj));
                    Socket soc = mServerSoc.Accept();
                    //WaitTimeOut 0 이상 설정한 경우 적용
                    if (mWaitTimeOut > 0)
                    {
                        soc.ReceiveTimeout = mWaitTimeOut;
                        soc.SendTimeout    = mWaitTimeOut;
                    }

                    lock (mClientTableLock)
                    {
                        StateObject stateObj = new StateObject(soc, "");
                        stateObj.Status     = SocHandlerStatus.CONNECTED;
                        stateObj.SocMessage = string.Format("Soc Accepted:{0}", soc.RemoteEndPoint.ToString());
                        Logger.info(stateObj);
                        OnSocStatusChangedOnInfo(new SocStatusEventArgs(stateObj));

                        mHtClientTable[soc.RemoteEndPoint.ToString()] = stateObj;

                        Thread thClient = new Thread(new ParameterizedThreadStart(this.ReceiveMsg));
                        thClient.Start(stateObj);
                    }
                }
            }
            catch (SocketException e)
            {
                if (e.ErrorCode == 10004) //정상 종료
                {
                    Logger.info("Socket errorCode[{0}]", e.ErrorCode);
                }
                else
                {
                    setErrorMessage(e, "Server Listening Error:" + e.ToString());
                }
            }
            catch (Exception e)
            {
                setErrorMessage(e, "Server Listening Error:" + e.ToString());
            }
        }
Beispiel #4
0
 public bool IsSocketReadyToReceive(StateObject obj)
 {
     return(obj.Status != SocHandlerStatus.DISCONNECTED && obj.Status != SocHandlerStatus.ERROR);
 }
Beispiel #5
0
        public virtual void ReceiveMsg(object stObj)
        {
            byte[] bufferTxtRcv      = new byte[SocConst.MAX_STR_BUFFER_SIZE];
            byte[] bufferBinRcv      = new byte[SocConst.TEMP_BUFFER_SIZE];
            byte[] bufferTxtStateObj = new byte[SocConst.MAX_STR_BUFFER_SIZE];
            byte[] bufferBinStateObj = new byte[SocConst.MAX_BUFFER_SIZE];

            StateObject stateObj  = (StateObject)stObj;
            Socket      clientSoc = stateObj.Soc;

            int connectionCheckCnt = 0;

            try
            {
                while (true) // An incoming connection needs to be processed.
                {
                    int recv = 0;
                    stateObj.BufferSize = 0;
                    stateObj.Data       = "";
                    stateObj.SocMessage = "";
                    byte[] buffer;
                    if (stateObj.FtpStatus == FTPStatus.RECEIVE_STREAM)//파일수신
                    {
                        Array.Clear(bufferBinRcv, 0, bufferBinRcv.Length);
                        buffer = bufferBinRcv;
                        Array.Clear(bufferBinStateObj, 0, bufferBinStateObj.Length);
                        stateObj.Buffer = bufferBinStateObj;
                    }
                    else //일반메시지
                    {
                        Array.Clear(bufferTxtRcv, 0, bufferTxtRcv.Length);
                        buffer = bufferTxtRcv;
                        Array.Clear(bufferTxtStateObj, 0, bufferTxtStateObj.Length);
                        stateObj.Buffer = bufferTxtStateObj;
                    }
                    Logger.debug("set buffer size =>" + buffer.Length);

                    //
                    if (!IsSocketReadyToReceive(stateObj))
                    {
                        stateObj.SocMessage = "소켓수신상태 Disconnected or Error.";
                        Logger.info(stateObj);
                        return;
                    }

                    int receivingByteInfo = 0;

                    while (true)//건별 메시지 수신
                    {
                        stateObj.Status = SocHandlerStatus.RECEIVING;
                        if (stateObj.FtpStatus != FTPStatus.RECEIVE_STREAM)//텍스트
                        {
                            stateObj.SocMessage = "메시지 수신대기";
                            Logger.debug(stateObj);
                            OnSocStatusChangedOnDebug(new SocStatusEventArgs(stateObj));
                        }
                        recv = clientSoc.Receive(buffer);

                        if (recv == 0)                   //수신데이터 없음
                        {
                            if (connectionCheckCnt > 10) //10회반복 데이터없으면 에러처리
                            {
                                stateObj.Data = string.Format(MsgDef.MSG_TEXT_FMT, MsgDef.MSG_TEXT, "TEST");
                                if (SendMsg(stateObj) == SocCode.SOC_ERR_CODE)
                                {
                                    stateObj.SocMessage = "소켓수신상태 Disconnected or Error.";
                                    Logger.info(stateObj);
                                    return;
                                }
                            }
                            connectionCheckCnt++;
                        }

                        if (stateObj.FtpStatus != FTPStatus.RECEIVE_STREAM)//텍스트
                        {
                            //텍스트는 메시지가 잘려서 넘어오는 경우보다
                            //여러건이 연결해서 한꺼번에 오는 경우가 있어 이를 감안함.
                            int msgBufSize = 0;
                            while (buffer.Length > 0)
                            {
                                //잘라서 처리
                                string resultMsg = SocUtils.GetMsgByPrefixLengthInfo(ref buffer, recv, ref msgBufSize);
                                if (resultMsg == null)
                                {
                                    break;
                                }

                                stateObj.Data       = resultMsg;
                                stateObj.BufferSize = msgBufSize;
                                stateObj.SocMessage = string.Format("일반메시지수신 Msg[{0}] Size[{0}]", stateObj.Data, stateObj.BufferSize);
                                Logger.debug(stateObj);
                                OnSocStatusChangedOnDebug(new SocStatusEventArgs(stateObj));
                                this.ProcessMsg(stateObj);
                            }
                        }
                        else
                        {
                            //FTP는 한 블록을 보낼때마다, 우선 블록사이즈정보를 보내고 실제바이트를 전송한다.
                            if (receivingByteInfo == 0)
                            {
                                receivingByteInfo = SocUtils.ConvertByteArrayToFileSize(buffer);
                                if (receivingByteInfo != 0)//블록사이즈정보있는 헤더
                                {
                                    recv = recv - SocConst.PREFIX_BYTE_INFO_LENGTH;
                                    //Logger.debug(string.Format("BlockCopy 헤더 receivingByteInfo[{0}]stateObj.BufferSize[{1}]recv[{2}]", receivingByteInfo, stateObj.BufferSize, recv));
                                    Buffer.BlockCopy(buffer, SocConst.PREFIX_BYTE_INFO_LENGTH, stateObj.Buffer, stateObj.BufferSize, recv);
                                }
                                else //중간부분
                                {    // error or abnormal stop , cancel
                                    //Logger.debug(string.Format("BlockCopy 헤더없는블록 receivingByteInfo[{0}]stateObj.BufferSize[{1}]recv[{2}]", receivingByteInfo, stateObj.BufferSize, recv));
                                    Buffer.BlockCopy(buffer, 0, stateObj.Buffer, stateObj.BufferSize, recv);
                                    stateObj.Data += Encoding.UTF8.GetString(buffer, 0, recv);
                                }
                                stateObj.SocMessage = string.Format("파일수신바이트[{0}].", recv);
                                //Logger.debug(string.Format("receivingByteInfo==0: receivingByteInfo[{0}]recv[{1}]", receivingByteInfo, recv));
                            }
                            else
                            {
                                //Logger.debug(string.Format("BlockCopy 중간부분 receivingByteInfo[{0}]stateObj.BufferSize[{1}]recv[{2}]", receivingByteInfo, stateObj.BufferSize, recv));
                                Buffer.BlockCopy(buffer, 0, stateObj.Buffer, stateObj.BufferSize, recv);
                                stateObj.SocMessage = string.Format("파일수신바이트[{0}].", recv);
                            }
                            stateObj.BufferSize += recv;
                            //Logger.debug(string.Format("stateObj.BufferSize += recv: stateObj.BufferSize[{0}]recv[{1}]", stateObj.BufferSize, recv));
                            //Logger.debug(stateObj.SocMessage);
                            //OnSocStatusChanged(new SocStatusEventArgs(stateObj));
                        }

                        if ((receivingByteInfo == 0 /*&& clientSoc.Available == 0*/) || //텍스트이거나,
                            (receivingByteInfo > 0 && receivingByteInfo == stateObj.BufferSize))    //바이너리인데 buffer리딩이 완료된 경우
                        {
                            break;
                        }
                    }//while (true)//건별 메시지 수신

                    if (receivingByteInfo > 0 && receivingByteInfo == stateObj.BufferSize) //바이너리인데 buffer리딩이 완료된 경우
                    {
                        stateObj.SocMessage = string.Format("메시지수신 완료바이트Size[{0}]", stateObj.BufferSize);
                        Logger.debug(stateObj);
                        OnSocStatusChangedOnDebug(new SocStatusEventArgs(stateObj));
                        this.ProcessMsg(stateObj);
                        //리셋
                        receivingByteInfo   = 0;
                        stateObj.BufferSize = 0;
                    }
                } //while (true)
            } catch (WeDoFTPCancelException wde) {
                CloseClient(clientSoc);
                StopListening();
                setErrorMessage(wde, stateObj);
            }
            catch (Exception e)
            {
                CloseClient(clientSoc);
                setErrorMessage(e, "수신에러:" + e.ToString());
            }
        }