' }string[] strsFileList = strMsg.Split(seperator)socketData.Close()//数据socket关闭时也会有返回码 if (iReplyCode != 226) { ReadReply()if (iReplyCode != 226) { throw new IOException(strReply.Substring(4))} } return strsFileList} /// /// 获取文件大小 /// /// 文件名 /// 文件大小 public long GetFileSize(string strFileName) { if (!bConnected) { Connect()} SendCommand("SIZE " + Path.GetFileName(strFileName))long lSize = 0if (iReplyCode == 213) { lSize = Int64.Parse(strReply.Substring(4))} else { throw new IOException(strReply.Substring(4))} return lSize} /// /// 删除 /// /// 待删除文件名 public void Delete(string strFileName) { if (!bConnected) { Connect()} SendCommand("DELE " + strFileName)if (iReplyCode != 250) { throw new IOException(strReply.Substring(4))} } /// /// 重命名(如果新文件名与已有文件重名,将覆盖已有文件) /// /// 旧文件名 /// 新文件名 public void Rename(string strOldFileName, string strNewFileName) { if (!bConnected) { Connect()} SendCommand("RNFR " + strOldFileName)if (iReplyCode != 350) { throw new IOException(strReply.Substring(4))} // 如果新文件名与原有文件重名,将覆盖原有文件 SendCommand("RNTO " + strNewFileName)if (iReplyCode != 250) { throw new IOException(strReply.Substring(4))} } #endregion #region 上传和下载 /// /// 下载一批文件 /// /// 文件名的匹配字符串 /// 本地目录(不得以\结束) public void Get(string strFileNameMask, string strFolder) { if (!bConnected) { Connect()} string[] strFiles = Dir(strFileNameMask)foreach (string strFile in strFiles) { if (!strFile.Equals(""))//一般来说strFiles的最后一个元素可能是空字符串 { if (strFile.LastIndexOf(".") >-1) { Get(strFile.Replace("\r", ""), strFolder, strFile.Replace("\r", ""))} } } } /// /// 下载一个文件 /// /// 要下载的文件名 /// 本地目录(不得以\结束) /// 保存在本地时的文件名 public void Get(string strRemoteFileName, string strFolder, string strLocalFileName) { if (!bConnected) { Connect()} SetTransferType(TransferType.Binary)if (strLocalFileName.Equals("")) { strLocalFileName = strRemoteFileName} if (!File.Exists(strLocalFileName)) { Stream st = File.Create(strLocalFileName)st.Close()} FileStream output = new FileStream(strFolder + "\\" + strLocalFileName, FileMode.Create)Socket socketData = CreateDataSocket()SendCommand("RETR " + strRemoteFileName)if (!(iReplyCode == 150 || iReplyCode == 125 || iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4))} while (true) { int iBytes = socketData.Receive(buffer, buffer.Length, 0)output.Write(buffer, 0, iBytes)if (iBytes <= 0) { break} } output.Close()if (socketData.Connected) { socketData.Close()} if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply()if (!(iReplyCode == 226 || iReplyCode == 250)) { throw new IOException(strReply.Substring(4))} } } /// /// 上传一批文件 /// /// 本地目录(不得以\结束) /// 文件名匹配字符(可以包含*和?) public void Put(string strFolder, string strFileNameMask) { string[] strFiles = Directory.GetFiles(strFolder, strFileNameMask)foreach (string strFile in strFiles) { //strFile是完整的文件名(包含路径) Put(strFile)} } /// /// 上传一个文件 /// /// 本地文件名 public void Put(string strFileName) { if (!bConnected) { Connect()} UpdateStatus = trueSocket socketData = CreateDataSocket()SendCommand("STOR " + Path.GetFileName(strFileName))if (!(iReplyCode == 125 || iReplyCode == 150)) { throw new IOException(strReply.Substring(4))} FileStream input = new FileStream(strFileName, FileMode.Open)int iBytes = 0long total = input.Lengthlong finished = 0//DateTime startTime = DateTime.Nowdouble speed = 0while ((iBytes = input.Read(buffer, 0, buffer.Length)) >0) { Console.WriteLine(startTime.ToString())socketData.Send(buffer, iBytes, 0)DateTime endTime = DateTime.NowTimeSpan ts = endTime - startTimefinished += iBytesConsole.WriteLine(ts.Milliseconds)if (ts.Milliseconds >0) { speed = (double)(finished / ts.TotalMilliseconds)speed = Math.Round(speed * 1000 / 1024, 2)} if (OnTransferProcess != null&&iBytes>0&&finished>0) { OnTransferProcess(total, finished,speed)} } UpdateStatus = falsefinished = 0input.Close()if (socketData.Connected) { socketData.Close()} if (!(iReplyCode == 226 || iReplyCode == 250)) { ReadReply()if (!(iReplyCode == 226 || iReplyCode == 250)) { UpdateStatus = falsethrow new IOException(strReply.Substring(4))} } } #endregion #region 目录 *** 作 /// /// 创建目录 /// /// 目录名 public void MkDir(string strDirName) { if (!bConnected) { Connect()} SendCommand("MKD " + strDirName)if (iReplyCode != 257) { throw new IOException(strReply.Substring(4))} } /// /// 删除目录 /// /// 目录名 public void RmDir(string strDirName) { if (!bConnected) { Connect()} SendCommand("RMD " + strDirName)if (iReplyCode != 250) { throw new IOException(strReply.Substring(4))} } /// /// 改变目录 /// /// 新的工作目录名 public void ChDir(string strDirName) { if (strDirName.Equals(".") || strDirName.Equals("")) { return} if (!bConnected) { Connect()} SendCommand("CWD " + strDirName)if (iReplyCode != 250) { throw new IOException(strReply.Substring(4))} this.strRemotePath = strDirName} #endregion #region 内部变量 /// /// 服务器返回的应答信息(包含应答码) /// private string strMsg/// /// 服务器返回的应答信息(包含应答码) /// private string strReply/// /// 服务器返回的应答码 /// private int iReplyCode/// /// 进行控制连接的socket /// private Socket socketControl/// /// 传输模式 /// private TransferType trType/// /// 接收和发送数据的缓冲区 /// private static int BLOCK_SIZE = Int16.MaxValueByte[] buffer = new Byte[BLOCK_SIZE]/// /// 编码方式(为防止出现中文乱码采用 GB2312编码方式) /// Encoding GB2312 = Encoding.Default //Encoding.GetEncoding("gb2312")#endregion #region 内部函数 /// /// 将一行应答字符串记录在strReply和strMsg /// 应答码记录在iReplyCode /// private void ReadReply() { strMsg = ""strReply = ReadLine()iReplyCode = Int32.Parse(strReply.Substring(0, 3))} /// /// 建立进行数据连接的socket /// /// 数据连接socket private Socket CreateDataSocket() { SendCommand("PASV")if (iReplyCode != 227) { throw new IOException(strReply.Substring(4))} int index1 = strReply.IndexOf('(')int index2 = strReply.IndexOf(')')string ipData = strReply.Substring(index1 + 1, index2 - index1 - 1)int[] parts = new int[6]int len = ipData.Lengthint partCount = 0string buf = ""for (int i = 0i <len &&partCount <= 6i++) { char ch = Char.Parse(ipData.Substring(i, 1))if (Char.IsDigit(ch)) buf += chelse if (ch != ',') { throw new IOException("Malformed PASV strReply: " + strReply)} if (ch == ',' || i + 1 == len) { try { parts[partCount++] = Int32.Parse(buf)buf = ""} catch (Exception) { throw new IOException("Malformed PASV strReply: " + strReply)} } } string ipAddress = parts[0] + "." + parts[1] + "." + parts[2] + "." + parts[3]int port = (parts[4] <<8) + parts[5]Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ipAddress), port)try { s.Connect(ep)} catch (Exception) { throw new IOException("无法连接服务器")} return s} /// /// 关闭socket连接(用于登录以前) /// private void CloseSocketConnect() { if (socketControl != null) { socketControl.Close()socketControl = null} bConnected = false} /// /// 读取Socket返回的所有字符串 /// /// 包含应答码的字符串行 private string ReadLine() { while (true) { int iBytes = socketControl.Receive(buffer, buffer.Length, 0)strMsg += GB2312.GetString(buffer, 0, iBytes)if (iBytes <buffer.Length) { break} } char[] seperator = { '
' }string[] mess = strMsg.Split(seperator)if (strMsg.Length >2) { strMsg = mess[mess.Length - 2]//seperator[0]是10,换行符是由13和0组成的,分隔后10后面虽没有字符串, //但也会分配为空字符串给后面(也是最后一个)字符串数组, //所以最后一个mess是没用的空字符串 //但为什么不直接取mess[0],因为只有最后一行字符串应答码与信息之间有空格 } else { strMsg = mess[0]} if (!strMsg.Substring(3, 1).Equals(" "))//返回字符串正确的是以应答码(如220开头,后面接一空格,再接问候字符串) { return ReadLine()} return strMsg} /// /// 发送命令并获取应答码和最后一行应答字符串 /// /// 命令 private void SendCommand(String strCommand) { Byte[] cmdBytes = GB2312.GetBytes((strCommand + "\r
").ToCharArray())socketControl.Send(cmdBytes, cmdBytes.Length, 0)ReadReply()} #endregion } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)