/// <summary> /// 确定当前路径下文件是否被其他下载 Socket 占用 /// </summary> /// <param name="path"></param> /// <returns></returns> private bool IsFileOccupying(string path) { lock (this.ServerFileSet) { List <int> ids = new List <int>(ServerFileSet.Keys); for (int i = 0; i < ids.Count; ++i) { ServerFileInfoClass p = ServerFileSet[ids[i]]; if (p.ServerPath == path) { // 若该 FileStream 不在使用中 (60s空闲) 则释放 if ((DateTime.Now - p.LastTime).Seconds > 60) { p.FStream.Close(); ServerFileSet.Remove(ids[i]); return(false); } else { return(true); } } } return(false); } }
/// <summary> /// /// </summary> /// <param name="client"></param> /// <param name="header"></param> /// <param name="bytes"></param> /// <param name="isUpload"></param> private void ResponseFileStreamId(Socket client, HB32Header header, byte[] bytes, bool isUpload) { SocketDataFlag mask = (SocketDataFlag)((isUpload ? 1 : 0) << 8); string path; /// 验证 key if (isUpload) { int keyLength = Config.KeyLength; byte[] key = new byte[keyLength]; Array.Copy(bytes, 0, key, 0, keyLength); path = BytesParser.ParseString(bytes, ref keyLength); if (!CheckKey(key)) { SendBytes(client, new HB32Header { Flag = SocketDataFlag.DownloadDenied ^ mask }, "key error"); return; } } else { path = Encoding.UTF8.GetString(bytes); } /// 验证文件是否被占用 if (IsFileOccupying(path)) { SendBytes(client, new HB32Header { Flag = SocketDataFlag.DownloadDenied ^ mask }, "file occupied"); return; } /// 生成 FileStreamId 并记录 try { FileInfo fif = new FileInfo(path); FileStream fs = new FileStream(path, FileMode.OpenOrCreate, isUpload ? FileAccess.Write : FileAccess.Read); ServerFileInfoClass record = new ServerFileInfoClass { FStream = fs, ServerPath = path, Length = fif.Length, }; int id = GenerateRandomFileStreamId(1 << 16); ServerFileSet.Add(id, record); SendBytes(client, new HB32Header { Flag = SocketDataFlag.DownloadAllowed ^ mask }, id.ToString()); } catch (Exception ex) { SendBytes(client, new HB32Header { Flag = SocketDataFlag.DownloadDenied ^ mask }, ex.Message); } }
/// <summary> /// /// </summary> /// <param name="client"></param> /// <param name="header"></param> /// <param name="bytes"></param> /// <param name="isUpload"></param> private void ResponseTransferPacket(Socket client, HB32Header header, byte[] bytes, bool isUpload) { ServerFileInfoClass sfc = ServerFileSet[header.I1]; FileStream fs = sfc.FStream; /// I2 == -1 则关闭 FileStream if (header.I2 == -1) { fs.Close(); ServerFileSet.Remove(header.I1); Display.TimeWriteLine("Released file id : " + header.I1.ToString()); return; } /// 确定有效 byte 长度 long begin = (long)header.I2 * HB32Encoding.DataSize; int length = HB32Encoding.DataSize; // 有效byte长度 if (begin + HB32Encoding.DataSize > sfc.Length) { length = (int)(sfc.Length - begin); } byte[] responseBytes = new byte[0]; /// 定位 FileStream 读取/写入 bytes lock (fs) { fs.Seek(begin, SeekOrigin.Begin); if (isUpload) { fs.Write(bytes, 0, header.ValidByteLength); //Display.TimeWriteLine(header.I2.ToString()); } else { responseBytes = new byte[length]; fs.Read(responseBytes, 0, length); } } sfc.LastTime = DateTime.Now; /// response if (isUpload) { SendHeader(client, new HB32Header { Flag = SocketDataFlag.UploadPacketResponse }); } else { SendBytes(client, new HB32Header { Flag = SocketDataFlag.DownloadPacketResponse }, responseBytes); } }