当前位置: 首页 > news >正文

北京模板建站广州网络公司政策

北京模板建站,广州网络公司政策,steam交易链接是什么,手机网址是什么1. 概要 通常对于一个正在执行的进程而言#xff0c;我们会关注进程的内存/CPU占用#xff0c;网络连接#xff0c;启动参数#xff0c;映像路径#xff0c;线程#xff0c;堆栈等信息。 而通过类似任务管理器#xff0c;命令行等方式可以轻松获取到这些信息。但是我们会关注进程的内存/CPU占用网络连接启动参数映像路径线程堆栈等信息。 而通过类似任务管理器命令行等方式可以轻松获取到这些信息。但是这些信息究竟是从何而来呢 linux 由于linux平台未直接提供进程信息的访问接口而是通过/proc文件系统向用户展示相关业务信息。虽然也可以通过neklink通信直接从内核获取我们想要的信息编码复杂性相对较高因此我们选择使用/proc文件系统的接口。Window windows平台原生提供了大量操作系统相关的接口但是每个接口的功能相对独立因此需要找到对应的接口查询数据最后将数据组装起来。 2. 进程列表 1linux /proc/[PID]/这是每个正在运行的进程都有一个对应的目录其中[PID]是进程的ID号。 DIR *proc opendir(/proc); if (proc) {struct dirent *entry;while ((entry readdir(proc)) ! NULL) {if (entry-d_type DT_DIR) {std::string dir_name(entry-d_name);if (dir_name.find_first_not_of(0123456789) std::string::npos) {int32_t pid atoi(entry-d_name);}}}closedir(proc); }2Window windows平台获取进程列表的方式比较多只需从中选择任意一种即可。 CreateToolhelp32Snapshot与Process32First等结合使用EnumProcesses枚举所有进程IDNtQuerySystemInformation查询SystemProcessInformation信息…… 在这里采用第一种方式遍历进程。 当然由于CreateToolhelp32Snapshot底层实际上同样是通过NtQuerySystemInformation实现的。因此若追求高效率的话可以使用第三种方案。 HANDLE hSnapshot CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0); if (hSnapshot) {PROCESSENTRY32 pe32;pe32.dwSize sizeof(pe32);if (Process32First(hSnapshot, pe32)) {do {std::string path;W2A(pe32.szExeFile, path);Proc detail_info;detail_info.pid pe32.th32ProcessID;detail_info.name path;// GetDetailInfoproc_map-emplace(pe32.th32ProcessID, detail_info);} while (Process32Next(hSnapshot, pe32));}CloseHandle(hSnapshot); }另附第三种方案实现 typedef NTSTATUS(NTAPI *P_NT_QUERY_SYSTEM_INFORMATION)(SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation,ULONG SystemInformationLength, PULONG ReturnLength);HMODULE hNtdll GetModuleHandle(Lntdll.dll); P_NT_QUERY_SYSTEM_INFORMATION pfnNtQueryInformationProcess NULL; if (hNtdll) {pfnNtQueryInformationProcess reinterpret_castP_NT_QUERY_SYSTEM_INFORMATION(GetProcAddress(hNtdll, NtQuerySystemInformation));ULONG length 0;PUCHAR pInfo NULL;do {DWORD result pfnNtQueryInformationProcess(SystemProcessInformation, pInfo,length, length); #define STATUS_INFO_LENGTH_MISMATCH 0xC0000004if (result ! 0) {if (result STATUS_INFO_LENGTH_MISMATCH) {pInfo new UCHAR[length];continue;}break;}PSYSTEM_PROCESS_INFORMATION _ProcessInfo;ULONG Offset 0;do {_ProcessInfo (PSYSTEM_PROCESS_INFORMATION)pInfo[Offset];int64_t pid HandleToLong(_ProcessInfo-UniqueProcessId);// ToDoOffset _ProcessInfo-NextEntryOffset;} while (_ProcessInfo-NextEntryOffset);break;} while (true);if (pInfo) {delete pInfo;} }SYSTEM_THREAD_INFORMATION具体结构请参考SYSTEM_PROCESS_INFORMATION 3. 参数列表 1linux /proc/[PID]/cmdline这个文件包含了启动该进程的命令行参数。参数之间使用null字符‘\0’分隔。 char cmd_path[PROCPATHLEN]; sprintf(cmd_path, /proc/%d/cmdline, pid);FILE *fp fopen(cmd_path, r); if (fp) {char line[4096];if (fgets(line, sizeof(line), fp)) {imagepath-assign(line);startparamater-assign(line);int32_t offset startparamater-size() 1;while (line[offset]) {startparamater-append( );startparamater-append(line offset);offset strlen(line offset) 1;}}fclose(fp); }2Window windows平台没有直接提供获取进程启动参数的接口但是可以通过解析进程的PEB进程环境块地址获取信息。 typedef NTSTATUS(NTAPI *NT_QUERY_INFORMATION_PROCESS)(HANDLE, PROCESSINFOCLASS,PVOID, ULONG, PULONG);HMODULE hNtdll GetModuleHandle(LNtdll); if (hNtdll) {NT_QUERY_INFORMATION_PROCESS pNtQueryInformationProcess (NT_QUERY_INFORMATION_PROCESS)GetProcAddress(hNtdll,NtQueryInformationProcess);if (pNtQueryInformationProcess) {// 只读打开进程句柄HANDLE hProcess OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);if (hProcess) {PWSTR buffer NULL;do {PROCESS_BASIC_INFORMATION pbi {0};// 读取进程基本信息RTL_USER_PROCESS_PARAMETERSif (pNtQueryInformationProcess(hProcess, ProcessBasicInformation, (PVOID)pbi,sizeof(PROCESS_BASIC_INFORMATION), NULL)) {break;}if (NULL pbi.PebBaseAddress) {break;}PEB peb;SIZE_T dwDummy;// 从PEB地址中读取PEB结构if (!ReadProcessMemory(hProcess, pbi.PebBaseAddress, peb, sizeof(peb),dwDummy)) {break;}RTL_USER_PROCESS_PARAMETERS para;// 从参数结构地址读取RTL_USER_PROCESS_PARAMETERS结构if (!ReadProcessMemory(hProcess, peb.ProcessParameters, para,sizeof(para), dwDummy)) {break;}// 从映像文件地址读取映像文件路径LPVOID lpAddress para.ImagePathName.Buffer;DWORD dwSize para.ImagePathName.Length;buffer new WCHAR[dwSize / sizeof(WCHAR) 1];buffer[dwSize / sizeof(WCHAR)] 0x00;if (!ReadProcessMemory(hProcess, lpAddress, buffer, dwSize, dwDummy)) {break;}W2A(buffer, imagepath);delete[] buffer;buffer NULL;// 从参数列表地址读取参数列表lpAddress para.CommandLine.Buffer;dwSize para.CommandLine.Length;buffer new WCHAR[dwSize / sizeof(WCHAR) 1];buffer[dwSize / sizeof(WCHAR)] 0x00;if (!ReadProcessMemory(hProcess, lpAddress, buffer, dwSize, dwDummy))break;W2A(buffer, startparamater);delete[] buffer;buffer NULL;result true;} while (false);if (buffer) {delete[] buffer;}CloseHandle(hProcess);}} }4. 动态库 1linux /proc/[PID]/maps这个文件包含了进程的内存映射信息显示了进程所使用的内存地址范围及其对应的权限。 char map_path[PROCPATHLEN]; sprintf(map_path, /proc/%d/maps, pid); FILE *fp fopen(map_path, r); if (fp) {char line[1024];char filename[1024];std::unordered_setstd::string module_sets;while (fgets(line, sizeof(line), fp)) {sscanf(line, %*s %*s %*s %*s %*ld %s, filename);if (filename[0] /) {module_sets.emplace(filename);}}fclose(fp);for (std::unordered_setstd::string::const_iterator itr module_sets.begin();itr ! module_sets.end(); itr) {ptable-push_back(*itr);} }2Window windows平台可以直接使用Module32First族函数遍历所有进程加载的模块。 HANDLE hSnapshot CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid); if (hSnapshot) {MODULEENTRY32 md32;md32.dwSize sizeof(md32);if (Module32First(hSnapshot, md32)) {do {std::string filepath;W2A(md32.szExePath, filepath);ptable-push_back(filepath);} while (Module32Next(hSnapshot, md32));}CloseHandle(hSnapshot); }5. CPU利用率 1linux 进程的Cpu利用率无法直接从系统获取而需要通过时间片算法来计算。在这里我们参考top命令实现简单的进程Cpu利用率计算。 算法 获取内核频率Hertz hertz_ sysconf(_SC_CLK_TCK)读取系统运行时间计算与上次的运行时间的差值et FILE *fp fopen(/proc/uptime, r);if (fp) {char line[1024];fgets(line, sizeof(line), fp);fclose(fp);sscanf(line, %lf, uptime);}计算刷新频率Frame_etscale float et uptime_cur - uptime_save_;if (et 0.01) {et 0.005;}uptime_save_ uptime_cur;frame_etscale_ 100.0f / ((float)hertz_ * (float)et * 1);遍历读取进程的用户态u_time和内核态时间s_time char stat_path[PROCPATHLEN];sprintf(stat_path, /proc/%d/stat, pid);FILE *fp fopen(stat_path, r);if (fp) {char line[1024];if (fgets(line, sizeof(line), fp)) {int64_t u_time, s_time, wait_u_time, wait_s_time, start_time;sscanf(line,%*d %*s %*c %*d %*d %*d %*d %*d %*lu %*lu %*lu %*lu %*lu%llu %llu %llu %llu%*ld %*ld %*d %*ld %llu , /* start_time */u_time, s_time, wait_u_time, wait_s_time, start_time);cpu_time-s_time s_time;cpu_time-u_time u_time;cpu_time-start_time start_time;}fclose(fp);}时间切片重复步骤2、3、4计算进程的CPU利用率cpu_usage ; tics process.new_time - process.old_time;cpu_usage tics * etscale_;2Window windows平台的算法与Linux类似。 算法 获取当前CPU时间 FILETIME idleTime, kernelTime, userTime;if (!GetSystemTimes(idleTime, kernelTime, userTime)) {return;}ULARGE_INTEGER cpu_time;cpu_time.LowPart kernelTime.dwLowDateTime userTime.dwLowDateTime;cpu_time.HighPart kernelTime.dwHighDateTime userTime.dwHighDateTime;time cpu_time.QuadPart;遍历所有进程的时间 HANDLE hProcess OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);if (hProcess) {FILETIME start_time, exit_time, s_time, u_time;if (!GetProcessTimes(hProcess, start_time, exit_time, s_time, u_time)) {return false;}FileTimeToInt64(s_time, cpu_time-s_time);FileTimeToInt64(u_time, cpu_time-u_time);FileTimeToInt64(start_time, cpu_time-start_time);CloseHandle(hProcess);}时间切片重复步骤1、2计算进程的CPU利用率cpu_usage ; *cpu_usage (process.new_time - process.old_time) * 1000 /(system_time_.new_time - system_time_.old_time);6. 内存占用 1linux /proc/[PID]/status这个文件包含了有关进程状态的各种信息如进程ID、父进程ID、运行状态、内存使用情况等。 // 获取物理内存总量单位Byte const char *meminfo_path /proc/meminfo; FILE *fp fopen(meminfo_path, r); if (fp) {char line[4096];while (fgets(line, sizeof(line), fp)) {if (strncmp(line, MemTotal:, 9) 0) {sscanf(line, %*s:%d, sys_mem_size_);break;}}fclose(fp); }//获取进程物理内存占用单位KB char status_path[PROCPATHLEN]; sprintf(status_path, /proc/%d/status, pid); FILE *fp fopen(status_path, r); if (fp) {char line[4096];while (fgets(line, sizeof(line), fp)) {if (strncmp(line, VmRSS:, 6) 0) {sscanf(line, %*s:%d, mem_used_size);break;}}fclose(fp); }2Window MEMORYSTATUSEX mem_info; mem_info.dwLength sizeof(mem_info); // 获取物理内存总量单位Byte if (GlobalMemoryStatusEx(mem_info)) {sys_mem_size_ mem_info.ullTotalPhys; }SYSTEM_INFO si; GetSystemInfo(si); HANDLE hProcess OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid); if (hProcess) {PSAPI_WORKING_SET_INFORMATION workset_info NULL;// 查询进程内存工具集if (!QueryWorkingSet(hProcess, workset_info, sizeof(workset_info))) {if (GetLastError() ERROR_BAD_LENGTH) {// 计算所需内存由于工具集长度动态变化因此在此多申请64个工具集空间。size_t length sizeof(PSAPI_WORKING_SET_INFORMATION) sizeof(PSAPI_WORKING_SET_BLOCK) * (workset_info.NumberOfEntries 64);PPSAPI_WORKING_SET_INFORMATION p_workset_info (PPSAPI_WORKING_SET_INFORMATION) new char[length];if (QueryWorkingSet(hProcess, p_workset_info, length)) {*mem_used_size 0;for (int i 0; i p_workset_info-NumberOfEntries; i) {// 判断工具集是否共享if (p_workset_info-WorkingSetInfo[i].Flags p_workset_info-WorkingSetInfo[i].Shared 0) {*mem_used_size si.dwPageSize;}}}delete[] (char *)p_workset_info;} else {return false;}}// Byte单位转换KB单位*mem_used_size (*mem_used_size / 1024);return true; }7. 用户名 1linux /proc/[PID]/status char status_path[PROCPATHLEN]; sprintf(status_path, /proc/%d/status, pid);FILE *fp fopen(status_path, r); if (fp) {char line[4096];while (fgets(line, sizeof(line), fp)) {if (strncmp(line, Uid:, 4) 0) {int32_t uid 0;sscanf(line, %*s:%d, uid);struct passwd *_passwd;_passwd getpwuid(uid);if (_passwd) {username _passwd-pw_name;}}}fclose(fp); }2Window HANDLE handle OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (handle ! 0x00) {HANDLE token;// 打开进程令牌if (OpenProcessToken(handle, TOKEN_QUERY, token)) {DWORD token_size 0;PTOKEN_USER p_token_user NULL;SID_NAME_USE sn;// 从进程令牌中获取用户令牌if (!GetTokenInformation(token, TokenUser, p_token_user, token_size,token_size)) {if (ERROR_INSUFFICIENT_BUFFER GetLastError()) {p_token_user (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, token_size);if (p_token_user) {if (GetTokenInformation(token, TokenUser, p_token_user, token_size,token_size)) {TCHAR szUserName[MAX_PATH] {0};DWORD dwUserSize MAX_PATH;TCHAR szDomain[MAX_PATH] {0};DWORD dwDomainSize MAX_PATH;// 根据用户令牌查询用户名if (LookupAccountSid(NULL, ((PTOKEN_USER)p_token_user)-User.Sid,szUserName, dwUserSize, szDomain,dwDomainSize, sn)) {W2A(szUserName, username);ret true;}}HeapFree(GetProcessHeap(), 0, p_token_user);}}}CloseHandle(token);}CloseHandle(handle); }8. 网络连接 1linux /proc/net/tcp /proc/net/tcp6 /proc/net/udp /proc/net/udp6 : 提供了当前 TCP /TCP6/UDP/UDP6套接字的详细信息。 /proc/[PID]/fd/这是一个文件夹包含了进程当前打开的文件描述符列表。 首先解析套接字信息包括套接字的inode号 const char *tcp_file[] {/proc/net/tcp, /proc/net/tcp6}; for (int i 0; i 2; i) {FILE *fp fopen(tcp_file[i], r);if (!fp) {return;}char line[1024];while (fgets(line, sizeof(line), fp)) {unsigned long rxq, txq, time_len, retr, inode;int num, local_port, remote_port, d, state, uid, timer_run, timeout;char rem_addr[128], local_addr[128];// 解析TCP信息num sscanf(line,%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %*s\n,d, local_addr, local_port, rem_addr, remote_port, state,txq, rxq, timer_run, time_len, retr, uid, timeout,inode);if (num 11) {continue;}// ipv6地址if (strlen(local_addr) 8) {char addr6[INET6_ADDRSTRLEN];struct in6_addr in6;sscanf(local_addr, %08X%08X%08X%08X, in6.s6_addr32[0],in6.s6_addr32[1], in6.s6_addr32[2], in6.s6_addr32[3]);// 端口序转换inet_ntop(AF_INET6, in6, addr6, sizeof(addr6));sscanf(rem_addr, %08X%08X%08X%08X, in6.s6_addr32[0], in6.s6_addr32[1],in6.s6_addr32[2], in6.s6_addr32[3]);inet_ntop(AF_INET6, in6, addr6, sizeof(addr6));} else {// ipv4地址char addr[INET_ADDRSTRLEN];struct in_addr in;sscanf(local_addr, %X, in.s_addr);inet_ntop(AF_INET, in, addr, sizeof(addr));sscanf(rem_addr, %X, in.s_addr);inet_ntop(AF_INET, in, addr, sizeof(addr));}}fclose(fp); }const char *udp_file[] {/proc/net/udp, /proc/net/udp6}; for (int i 0; i 2; i) {FILE *fp fopen(udp_file[i], r);if (!fp) {return false;}char line[1024];while (fgets(line, sizeof(line), fp)) {unsigned long rxq, txq, time_len, retr, inode;int num, local_port, remote_port, d, state, uid, timer_run, timeout;char rem_addr[128], local_addr[128];// 解析UDP信息num sscanf(line,%d: %64[0-9A-Fa-f]:%X %64[0-9A-Fa-f]:%X %X %lX:%lX %X:%lX %lX %d %d %lu %*s\n,d, local_addr, local_port, rem_addr, remote_port, state,txq, rxq, timer_run, time_len, retr, uid, timeout,inode);if (num 10) {continue;}if (strlen(local_addr) 8) {// ipv6地址char addr6[INET6_ADDRSTRLEN];struct in6_addr in6;sscanf(local_addr, %08X%08X%08X%08X, in6.s6_addr32[0],in6.s6_addr32[1], in6.s6_addr32[2], in6.s6_addr32[3]);inet_ntop(AF_INET6, in6, addr6, sizeof(addr6));} else {// ipv4地址char addr[INET_ADDRSTRLEN];struct in_addr in;sscanf(local_addr, %X, in.s_addr);inet_ntop(AF_INET, in, addr, sizeof(addr));}}fclose(fp); }遍历所有进程的fd文件夹匹配inode号。 2WIndows 直接使用GetExtendedTcpTable和GetExtendedUdpTable函数查询TCP和UDP信息。 DWORD bufferSize; MIB_TCPTABLE_OWNER_PID *net_table NULL;WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), wsaData)) {return; }do {SOCKADDR_IN v4 {AF_INET};SOCKADDR_IN6 v6 {AF_INET6};int32_t ip[] {AF_INET6, AF_INET};char ipaddress[INET6_ADDRSTRLEN];DWORD ipaddress_length 0;for (int i 0; i 2; i) {bufferSize 0;if (GetExtendedTcpTable(NULL, bufferSize, FALSE, ip[i],TCP_TABLE_OWNER_PID_ALL,0) ERROR_INSUFFICIENT_BUFFER) {BYTE *net_table new BYTE[bufferSize];if (net_table ! NULL) {if (GetExtendedTcpTable(net_table, bufferSize, FALSE, ip[i],TCP_TABLE_OWNER_PID_ALL, 0) NO_ERROR) {if (i 0) {MIB_TCP6TABLE_OWNER_PID *net_table_v6 (MIB_TCP6TABLE_OWNER_PID *)net_table;for (DWORD i 0; i net_table_v6-dwNumEntries; i) {MIB_TCP6ROW_OWNER_PID row net_table_v6-table[i];// local addr infoipaddress_length INET6_ADDRSTRLEN;memcpy(v6.sin6_addr.s6_addr, row.ucLocalAddr,sizeof(row.ucLocalAddr));if (!WSAAddressToStringA((LPSOCKADDR)v6, sizeof(v6), NULL,ipaddress, ipaddress_length)) {local_host ipaddress;}local_port ntohs(row.dwLocalPort);// remote addr infoipaddress_length INET6_ADDRSTRLEN;memcpy(v6.sin6_addr.s6_addr, row.ucRemoteAddr,sizeof(row.ucRemoteAddr));if (!WSAAddressToStringA((LPSOCKADDR)v6, sizeof(v6), NULL,ipaddress, ipaddress_length)) {remote_host ipaddress;}remote_port ntohs(row.dwRemotePort);}} else {MIB_TCPTABLE_OWNER_PID *net_table_v4 (MIB_TCPTABLE_OWNER_PID *)net_table;for (DWORD i 0; i net_table_v4-dwNumEntries; i) {MIB_TCPROW_OWNER_PID row net_table_v4-table[i];// local addr infoipaddress_length INET_ADDRSTRLEN;v4.sin_addr.s_addr row.dwLocalAddr;if (!WSAAddressToStringA((LPSOCKADDR)v4, sizeof(v4), NULL,ipaddress, ipaddress_length)) {local_host ipaddress;}local_port ntohs(row.dwLocalPort);// remote addr infoipaddress_length INET_ADDRSTRLEN;v4.sin_addr.s_addr row.dwRemoteAddr;if (!WSAAddressToStringA((LPSOCKADDR)v4, sizeof(v4), NULL,ipaddress, ipaddress_length)) {remote_host ipaddress;}remote_port ntohs(row.dwRemotePort);}}}delete[] net_table;}}}for (int i 0; i 2; i) {bufferSize 0;if (GetExtendedUdpTable(NULL, bufferSize, FALSE, ip[i],UDP_TABLE_OWNER_PID,0) ERROR_INSUFFICIENT_BUFFER) {BYTE *net_table new BYTE[bufferSize];if (net_table ! NULL) {if (GetExtendedUdpTable(net_table, bufferSize, FALSE, ip[i],UDP_TABLE_OWNER_PID, 0) NO_ERROR) {if (i 0) {MIB_UDP6TABLE_OWNER_PID *net_table_v6 (MIB_UDP6TABLE_OWNER_PID *)net_table;for (DWORD i 0; i net_table_v6-dwNumEntries; i) {MIB_UDP6ROW_OWNER_PID row net_table_v6-table[i];// local addr netInfoipaddress_length INET6_ADDRSTRLEN;memcpy(v6.sin6_addr.s6_addr, row.ucLocalAddr,sizeof(row.ucLocalAddr));if (!WSAAddressToStringA((LPSOCKADDR)v6, sizeof(v6), NULL,ipaddress, ipaddress_length)) {local_host ipaddress;}local_port ntohs(row.dwLocalPort);}} else {MIB_UDPTABLE_OWNER_PID *net_table_v4 (MIB_UDPTABLE_OWNER_PID *)net_table;for (DWORD i 0; i net_table_v4-dwNumEntries; i) {MIB_UDPROW_OWNER_PID row net_table_v4-table[i];// local addr netInfoipaddress_length INET_ADDRSTRLEN;v4.sin_addr.s_addr row.dwLocalAddr;if (!WSAAddressToStringA((LPSOCKADDR)v4, sizeof(v4), NULL,ipaddress, ipaddress_length)) {local_host ipaddress;}local_port ntohs(row.dwLocalPort);}}}delete[] net_table;}}} } while (false); WSACleanup();9. 待续 ……
http://wiki.neutronadmin.com/news/232290/

相关文章:

  • 销售珍珠网站建设策划书福建省城乡住房建设厅网站
  • 网站建设的基本步骤是吉林市城市建设管理执法局网站
  • 福建省建设工程信息网站天津做网站选津坤科技
  • 做网站vpn多大内存企业网站建设招标文件
  • 免费建站哪个好推广网站建设花费得多少钱
  • 西安网站建设的费用如何查询网站接入信息
  • 学网站建设要多少钱成都家具公司
  • 美食网站二级页面模板新闻发布平台有哪些
  • 手机自己制作表白网站网站制作多少费用
  • 有网站做点什么好去哪找做网站的人
  • 网站建设实施计划包括福建刚刚发生大事
  • 中国建设银行官网站陕西西安网站设计制作是什么
  • asp网站发布ftp排名优化网站seo排名
  • 自己的网站服务器北京网站建设首选小峰
  • 自建站外贸平台有哪些比较好全网品牌营销
  • 网站开发需要的学历手机网站功能
  • 做网站拉广告网络营销是什么的产生主要源于网络市场的复杂性
  • 炫酷表白网站在线制作ps怎么做网站横幅广告
  • 网站做动态图片大全共享虚拟主机 几个网站
  • 网站上线需要哪些步骤青岛网站运营
  • 帮人做ppt的网站wordpress文章阅读统计
  • 许昌网站优化科技信息网站系统建设方案
  • 深圳中高端网站建设怎么样京东商城网站建设策划书
  • 濮阳哪里做网站百度舆情系统
  • 建设工程月评打分网站做移动网站快速
  • wordpress 商务 主题wordpress分类目录优化
  • 建站平台的基础概念班级网站建设组织机构
  • 广州洲聚网站开发外贸局是做什么的工作
  • 北碚免费建站哪家做得好seo的含义
  • 唐山建网站公司浪花直播