/// <summary> /// receive pack header /// </summary> /// <param name="input">input stream</param> /// <param name="expect_cmd">expect response command</param> /// <param name="expect_body_len">expect response package body length</param> /// <returns>errno and pkg body length</returns> public static RecvHeaderInfo recvHeader(Stream input, byte expect_cmd, long expect_body_len) { byte[] header; int bytes; long pkg_len; header = new byte[FDFS_PROTO_PKG_LEN_SIZE + 2]; if ((bytes = input.Read(header, 0, header.Length)) != header.Length) { throw new IOException("recv package size " + bytes + " != " + header.Length); } if (header[PROTO_HEADER_CMD_INDEX] != expect_cmd) { throw new IOException("recv cmd: " + header[PROTO_HEADER_CMD_INDEX] + " is not correct, expect cmd: " + expect_cmd); } if (header[PROTO_HEADER_STATUS_INDEX] != 0) { return(new RecvHeaderInfo(header[PROTO_HEADER_STATUS_INDEX], 0)); } //pkg_len = BitConverter.ToInt64(header, 0); pkg_len = ProtoCommon.buff2long(header, 0); if (pkg_len < 0) { throw new IOException("recv body length: " + pkg_len + " < 0!"); } if (expect_body_len >= 0 && pkg_len != expect_body_len) { throw new IOException("recv body length: " + pkg_len + " is not correct, expect length: " + expect_body_len); } return(new RecvHeaderInfo((byte)0, pkg_len)); }
protected DateTime dateValue(byte[] bs, int offset, FieldInfo filedInfo) { //return new DateTime(BitConverter.ToInt64(bs, offset + filedInfo.Offset) * 1000); return(ProtoCommon.UnixTimestampToDateTime(ProtoCommon.buff2long(bs, offset + filedInfo.Offset))); }
protected int intValue(byte[] bs, int offset, FieldInfo filedInfo) { //return BitConverter.ToInt16(bs, offset + filedInfo.Offset); return((int)ProtoCommon.buff2long(bs, offset + filedInfo.Offset)); }
protected long longValue(byte[] bs, int offset, FieldInfo filedInfo) { //return BitConverter.ToInt64(bs, offset + filedInfo.Offset); return(ProtoCommon.buff2long(bs, offset + filedInfo.Offset)); }
/// <summary> /// query storage server to upload file /// </summary> /// <param name="trackerServer">the tracker server</param> /// <param name="groupName">the group name to upload file to, can be empty</param> /// <returns>storage server object, return null if fail</returns> public StorageServer getStoreStorage(TrackerServer trackerServer, string groupName) { byte[] header; string ip_addr; int port; byte cmd; int out_len; bool bNewConnection; byte store_path; TcpClient trackerSocket; if (trackerServer == null) { trackerServer = getConnection(); if (trackerServer == null) { return(null); } bNewConnection = true; } else { bNewConnection = false; } trackerSocket = trackerServer.getSocket(); Stream output = trackerSocket.GetStream(); try { if (groupName == null || groupName.Length == 0) { cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITHOUT_GROUP_ONE; out_len = 0; } else { cmd = ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_STORE_WITH_GROUP_ONE; out_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN; } header = ProtoCommon.packHeader(cmd, out_len, (byte)0); output.Write(header, 0, header.Length); if (groupName != null && groupName.Length > 0) { byte[] bGroupName; byte[] bs; int group_len; bs = Encoding.GetEncoding(ClientGlobal.g_charset).GetBytes(groupName); bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN]; if (bs.Length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) { group_len = bs.Length; } else { group_len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN; } for (int i = 0; i < bGroupName.Length; i++) { bGroupName[i] = (byte)0; } Array.Copy(bs, 0, bGroupName, 0, group_len); output.Write(bGroupName, 0, bGroupName.Length); } ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.GetStream(), ProtoCommon.TRACKER_PROTO_CMD_RESP, ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN); this.errno = pkgInfo.errno; if (pkgInfo.errno != 0) { return(null); } ip_addr = Encoding.GetEncoding(ClientGlobal.g_charset).GetString(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE - 1).Replace("\0", "").Trim(); port = (int)ProtoCommon.buff2long(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ProtoCommon.FDFS_IPADDR_SIZE - 1); store_path = pkgInfo.body[ProtoCommon.TRACKER_QUERY_STORAGE_STORE_BODY_LEN - 1]; return(new StorageServer(ip_addr, port, store_path)); } catch (IOException ex) { if (!bNewConnection) { try { trackerServer.close(); } catch (IOException ex1) { } } throw ex; } finally { if (bNewConnection) { try { trackerServer.close(); } catch (IOException ex1) { } } } }
/// <summary> /// query storage server to download file /// </summary> /// <param name="trackerServer">the tracker server</param> /// <param name="cmd">command code, ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_FETCH_ONE or ProtoCommon.TRACKER_PROTO_CMD_SERVICE_QUERY_UPDATE</param> /// <param name="groupName">the group name of storage server</param> /// <param name="filename">filename on storage server</param> /// <returns>storage server Socket object, return null if fail</returns> protected ServerInfo[] getStorages(TrackerServer trackerServer, byte cmd, string groupName, string filename) { byte[] header; byte[] bFileName; byte[] bGroupName; byte[] bs; int len; string ip_addr; int port; bool bNewConnection; TcpClient trackerSocket; if (trackerServer == null) { trackerServer = getConnection(); if (trackerServer == null) { return(null); } bNewConnection = true; } else { bNewConnection = false; } trackerSocket = trackerServer.getSocket(); Stream output = trackerSocket.GetStream(); try { bs = Encoding.GetEncoding(ClientGlobal.g_charset).GetBytes(groupName); bGroupName = new byte[ProtoCommon.FDFS_GROUP_NAME_MAX_LEN]; bFileName = Encoding.GetEncoding(ClientGlobal.g_charset).GetBytes(filename); if (bs.Length <= ProtoCommon.FDFS_GROUP_NAME_MAX_LEN) { len = bs.Length; } else { len = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN; } for (int i = 0; i < bGroupName.Length; i++) { bGroupName[i] = (byte)0; } Array.Copy(bs, 0, bGroupName, 0, len); header = ProtoCommon.packHeader(cmd, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + bFileName.Length, (byte)0); byte[] wholePkg = new byte[header.Length + bGroupName.Length + bFileName.Length]; Array.Copy(header, 0, wholePkg, 0, header.Length); Array.Copy(bGroupName, 0, wholePkg, header.Length, bGroupName.Length); Array.Copy(bFileName, 0, wholePkg, header.Length + bGroupName.Length, bFileName.Length); output.Write(wholePkg, 0, wholePkg.Length); ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(trackerSocket.GetStream(), ProtoCommon.TRACKER_PROTO_CMD_RESP, -1); this.errno = pkgInfo.errno; if (pkgInfo.errno != 0) { return(null); } if (pkgInfo.body.Length < ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) { throw new IOException("Invalid body length: " + pkgInfo.body.Length); } if ((pkgInfo.body.Length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) % (ProtoCommon.FDFS_IPADDR_SIZE - 1) != 0) { throw new IOException("Invalid body length: " + pkgInfo.body.Length); } int server_count = 1 + (pkgInfo.body.Length - ProtoCommon.TRACKER_QUERY_STORAGE_FETCH_BODY_LEN) / (ProtoCommon.FDFS_IPADDR_SIZE - 1); ip_addr = Encoding.GetEncoding(ClientGlobal.g_charset).GetString(pkgInfo.body, ProtoCommon.FDFS_GROUP_NAME_MAX_LEN, ProtoCommon.FDFS_IPADDR_SIZE - 1).Replace("\0", "").Trim(); int offset = ProtoCommon.FDFS_GROUP_NAME_MAX_LEN + ProtoCommon.FDFS_IPADDR_SIZE - 1; port = (int)ProtoCommon.buff2long(pkgInfo.body, offset); offset += ProtoCommon.FDFS_PROTO_PKG_LEN_SIZE; ServerInfo[] servers = new ServerInfo[server_count]; servers[0] = new ServerInfo(ip_addr, port); for (int i = 1; i < server_count; i++) { servers[i] = new ServerInfo(Encoding.GetEncoding(ClientGlobal.g_charset).GetString(pkgInfo.body, offset, ProtoCommon.FDFS_IPADDR_SIZE - 1).Replace("\0", "").Trim(), port); offset += ProtoCommon.FDFS_IPADDR_SIZE - 1; } return(servers); } catch (IOException ex) { if (!bNewConnection) { try { trackerServer.close(); } catch (IOException ex1) { } } throw ex; } finally { if (bNewConnection) { try { trackerServer.close(); } catch (IOException ex1) { } } } }