private void OpenPassiveDataConnection()
        {
            if (m_DataSocket != null)
            { // Through some exception here because passed socket is already in use
                throw new ProtocolViolationException();
            }
            String IPAddressStr = null;
            int    Port         = 0;

            SendCommand("PASV", "");

            //FtpWebResponse response = ReceiveResponse();
            ResponseDescription resp_desc = ReceiveCommandResponse();

            if (!resp_desc.PositiveCompletion)
            {
                // throw some exception here
                throw new ApplicationException("Imposible abrir conexión de datos pasiva\n" + ComposeExceptionMessage(resp_desc, m_sbControlSocketLog.ToString()));
            }

            //Console.WriteLine(resp_desc.StatusDescription);
            //Find the IPAddress and port address from response
            IPAddressStr = getIPAddress(resp_desc.StatusDescription);
            Port         = getPort(resp_desc.StatusDescription);

            m_DataSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            if (m_DataSocket == null)
            {
                throw new ProtocolViolationException("Error al crear el Socket para datos");
            }

            IPHostEntry serverHostEntry = Dns.GetHostByName(m_RequestUri.Host);

            IPEndPoint serverEndPoint = new IPEndPoint(serverHostEntry.AddressList[0], Port);

            //IPEndPoint  serverEndPoint = new IPEndPoint(IPAddress.Parse(IPAddressStr), Port);

            try
            {
                m_DataSocket.Connect(serverEndPoint);
            }
            catch
            {
                m_DataSocket.Close();
                m_DataSocket = null;
                throw new ProtocolViolationException("Fallo de conexión pasiva");
            }

            return;
        }
        internal string ComposeExceptionMessage(ResponseDescription resp_desc, string log)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("FTP Protocol Error.....\n");
            sb.Append("Status: " + resp_desc.Status + "\n");
            sb.Append("Description: " + resp_desc.StatusDescription + "\n");
            sb.Append("\n");

            sb.Append("--------------------------------\n");
            sb.Append(log);
            sb.Append("\n");

            return(sb.ToString());
        }
        private ResponseDescription ReceiveCommandResponse()
        {
            ResponseDescription resp_desc = new ResponseDescription();

            int    StatusCode        = 0;
            String StatusDescription = null;

            bool bCompleteResponse = false;

            if (m_ControlSocket == null) // something went wrong protocol violation exception
            {
                throw new ApplicationException("Conexión de control cerrada");
            }

            MemoryStream responseStream = new MemoryStream();

            while (true)
            {
                int    BufferSize = 256;
                Byte[] recvbuffer = new Byte[BufferSize + 1];
                int    bytesread  = 0;
                recvbuffer[0] = (Byte)'\0';
                bytesread     = m_ControlSocket.Receive(recvbuffer, BufferSize, 0);

                if (bytesread <= 0)
                {
                    break; // No response recieve to process, exit the loop
                }
                //copy the recieved data in responsestream
                responseStream.Write(recvbuffer, 0, bytesread);

                String szResponse = Encoding.ASCII.GetString(recvbuffer, 0, bytesread);
                m_sbControlSocketLog.Append(szResponse);

                bCompleteResponse = IsCompleteResponse(responseStream);
                if (bCompleteResponse)
                {
                    break;
                }
            }

            // @TODO: Remove this stream stuff, and read from stringbuffer instead.
            if (bCompleteResponse)
            {
                // now get status code
                try
                {
                    responseStream.Position = 0;
                    Byte [] bStatusCode = new Byte[3];
                    responseStream.Read(bStatusCode, 0, 3);
                    String statuscodestr = Encoding.ASCII.GetString(bStatusCode, 0, 3);
                    StatusCode = Convert.ToInt16(statuscodestr);
                }
                catch
                {
                    StatusCode = -1;
                }
                //
                // Copy the response in Status Description
                //
                int responsesize = (int)responseStream.Length;
                responseStream.Position = 0;
                Byte [] bStatusDescription = new Byte[responsesize];
                responseStream.Read(bStatusDescription, 0, responsesize);

                StatusDescription = Encoding.ASCII.GetString(bStatusDescription, 4, responsesize - 4);
            }
            else
            {
                // something went wrong here
                throw new ProtocolViolationException();
            }

            resp_desc.Status            = StatusCode;
            resp_desc.StatusDescription = StatusDescription;

            return(resp_desc);
        }
        private WebResponse GetFtpResponse()
        {
            FtpWebResponse ftpresponse = null;

            if (m_CommandType == FtpCommandType.FtpDataReceiveCommand ||
                m_CommandType == FtpCommandType.FtpDataSendCommand)
            {
                if (_bPassiveMode)
                {
                    OpenPassiveDataConnection();
                }
                else
                {
                    OpenDataConnection();
                }
            }

            //
            // negotiate data connection
            //
            string sztype = "I";

            if (m_szContentType == "ascii")
            {
                sztype = "A";
            }

            SendCommand("TYPE", sztype);

            ResponseDescription resp_desc = ReceiveCommandResponse();

            if (!resp_desc.PositiveCompletion)
            {
                throw new ApplicationException("Negociación de datos fallida:\n" + m_sbControlSocketLog.ToString());
            }

            if (m_szServerMethod == "PWD")
            {
                m_szCmdParameter = null;
            }

            SendCommand(m_szServerMethod, m_szCmdParameter);

            //ftpresponse = ReceiveResponse();
            resp_desc = ReceiveCommandResponse();

            if (m_CommandType == FtpCommandType.FtpDataSendCommand)
            {
                //if(resp_desc.Status/100 == 1) // Positive preliminary reply
                if (resp_desc.PositivePreliminary) // Positive preliminary reply
                {
                    if (m_RequestStream != null)
                    {
                        Socket DataConnection;
                        if (_bPassiveMode)
                        {
                            DataConnection = m_DataSocket;
                        }
                        else
                        {
                            DataConnection = m_DataSocket.Accept();
                        }
                        if (DataConnection == null)
                        {
                            throw new ProtocolViolationException("Accept failed ");
                        }

                        SendData(DataConnection);
                        DataConnection.Close();

                        //ftpresponse = ReceiveResponse();
                        ResponseDescription resp = ReceiveCommandResponse();

                        ftpresponse = new FtpWebResponse(resp.Status, resp.StatusDescription, m_sbControlSocketLog.ToString());
                    }
                    else
                    { // Data to be send is not specified
                        throw new ApplicationException("Data to be uploaded not specified");
                    }
                }
                else
                {
                    //Console.WriteLine(resp_desc.StatusDescription);
                    m_Exception = new ApplicationException(ComposeExceptionMessage(resp_desc, m_sbControlSocketLog.ToString()));
                }
                CloseDataConnection();
            }
            else if (m_CommandType == FtpCommandType.FtpDataReceiveCommand)
            {
                //if(resp_desc.Status/100 == 1) // Positive preliminary reply
                if (resp_desc.PositivePreliminary) // Positive preliminary reply
                {
                    Socket DataConnection;
                    if (_bPassiveMode)
                    {
                        DataConnection = m_DataSocket;
                    }
                    else
                    {
                        DataConnection = m_DataSocket.Accept();
                    }
                    if (DataConnection == null)
                    {
                        throw new ProtocolViolationException("Conexión de datos fallida ");
                    }
                    Stream datastream = ReceiveData(DataConnection);
                    DataConnection.Close();

                    //ftpresponse = ReceiveResponse();
                    ResponseDescription resp = ReceiveCommandResponse();
                    ftpresponse = new FtpWebResponse(resp.Status, resp.StatusDescription, m_sbControlSocketLog.ToString());
                    ftpresponse.SetDownloadStream(datastream);
                }
                else
                {
                    m_Exception = new ApplicationException(ComposeExceptionMessage(resp_desc, m_sbControlSocketLog.ToString()));
                }

                CloseDataConnection();
            }
            else
            {
                //
                // htis is a FtpControlCommand
                //
                ftpresponse = new FtpWebResponse(resp_desc.Status, resp_desc.StatusDescription, m_sbControlSocketLog.ToString());
            }

            if (m_Exception != null)
            {
                Debug.Assert(ftpresponse == null);
                throw m_Exception;
            }

            return(ftpresponse);
        }