需要共享资源,则需要探测本地资源分布情况。
此处我们用的算法比较2……不过还是说说吧。
下面使用MFC的CFileFind实现一个本地文件递归收集器,以jason格式存储文件路径和文件大小:
#ifndef COLLECTER_H_
#define COLLECTER_H_
#include<iostream>
#include<vector>
#include "StdioFileEx/StdioFileEx.h"
#define TargetFile "result.txt"
#define CfgFileName "path.txt"
using namespace std;
struct FileStruct
{
CString path;
__int64 size;
};
vector<FileStruct> files;
void findfile(CString dir)
{
CFileFind finder;
BOOL bWorking = finder.FindFile(dir + _T("\\*.*"));
while (bWorking)
{
bWorking = finder.FindNextFile();
//列举文件
if( finder.IsDots() == false && finder.IsDirectory() == false )
{
FileStruct file;
CString tmp = dir + _T("\\") + CString( finder.GetFileName() );
//只传送文件名
//CString tmp = CString( finder.GetFileName() );
file.path = tmp;
__int64 iFileLenInByte = (__int64)finder.GetLength();
__int64 size = iFileLenInByte;
file.size = size;
files.push_back( file );
}
//递归访问子目录
if( finder.IsDirectory() &&
finder.IsDots() == false )
findfile( dir + _T("\\") + CString( finder.GetFileName() ) );
}
}
/*
[{"f_name":"文件名","f_hash":"文件哈希,32字符","f_length":null/片长,数字不要加引号,"f_type":null/"文件类型就后缀吧先","f_time":null/"年代字符串 加双引号","f_intro":"简介,类似年代"},{}...{}]
*/
void WriteResult()
{
CStdioFileEx fp;
fp.Open(_T(TargetFile),CFile::modeWrite|CFile::modeCreate);
fp.WriteString( _T("["));
for( vector<FileStruct>::iterator iter = files.begin(); iter != files.end(); ++iter)
{
if( iter != files.begin() )
fp.WriteString(_T(","));
CString MyFileSize;
MyFileSize.Format(_T("%ld"),iter->size);
fp.WriteString(_T("{\"fname\":\""));
fp.WriteString( iter->path );
fp.WriteString(_T("\","));
fp.WriteString(_T("\"fsize\":\""));
fp.WriteString( MyFileSize );
fp.WriteString(_T("\"}"));
//fp.WriteString( iter->size );
}
fp.WriteString( _T("]"));
fp.Close();
}
void ReadCfg(CString& path)
{
CStdioFileEx fp;
fp.Open(_T(CfgFileName),CFile::modeRead);
fp.ReadString( path );
fp.Close();
}
void StartCollect()
{
CString SearchPath;
ReadCfg( SearchPath );
cout<<"searching please wait."<<endl;;
findfile( SearchPath );
WriteResult();
cout<<"finish"<<endl;
system("pause");
}
#endif
然后定期收集,对收集结果MD5,若发生变化,则上传服务器。
服务器端使用一个数据结构维护所有资源站资源,对于用户的搜索,我们此处使用最简单的比较方法,看是否包含子串,此处就不详加介绍了。
服务器对所有的客户端进行集中管理,需要维护一张在线用户列表。
关于服务器如何探测资源站是否在线,TCP主动的的连接与断开可以检测到,但是若是被动的断线等,是无法正确响应的。所以此处我们还是使用心跳包模型——客户端每隔一段时间就向服务器发送心跳包,证明自己还“活着”,服务器若长时间没有收到某个客户端的心跳,则认为它“死掉”了,就从在线列表里将其KICK。
服务器端我们是使用的CONSOLE管理,实际就是单开一个control线程,可以由管理员输入命令进行管理。如查询在线列表、查询资源、踢出用户、广播消息等,这里也不加详细介绍了。
服务器需要维护LOG文件,如下所示:
【2010-01-25 9:0:24】开启服务器
【2010-01-25 9:0:31】127.0.0.1登入服务器
【2010-01-25 9:0:31】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:1:32】127.0.0.1长时间未响应,从服务器移除
【2010-01-25 9:3:20】开启服务器
【2010-01-25 9:3:23】0.0.0.0申请搜索,关键字 =
【2010-01-25 9:3:30】开启服务器
【2010-01-25 9:3:34】127.0.0.1登入服务器
【2010-01-25 9:3:34】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:3:37】0.0.0.0申请搜索,关键字 =
【2010-01-25 9:3:42】0.0.0.0申请搜索,关键字 = 1
【2010-01-25 9:4:14】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:5:19】127.0.0.1广播消息:sss
【2010-01-25 9:5:21】127.0.0.1广播消息:ahaha
【2010-01-25 9:5:23】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:6:0】127.0.0.1长时间未响应,从服务器移除
【2010-01-25 9:7:9】127.0.0.1登入服务器
【2010-01-25 9:7:9】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:7:46】127.0.0.1长时间未响应,从服务器移除
【2010-01-25 9:9:25】127.0.0.1登入服务器
【2010-01-25 9:9:26】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:14:39】127.0.0.1登入服务器
【2010-01-25 9:15:15】127.0.0.1长时间未响应,从服务器移除
【2010-01-25 9:17:33】127.0.0.1登入服务器
【2010-01-25 9:17:33】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:17:42】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:18:41】127.0.0.1长时间未响应,从服务器移除
【2010-01-25 9:19:7】127.0.0.1登入服务器
【2010-01-25 9:19:8】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:19:45】127.0.0.1长时间未响应,从服务器移除
【2010-01-25 9:20:6】127.0.0.1登入服务器
【2010-01-25 9:20:7】127.0.0.1申请搜索,关键字 =
【2010-01-25 9:21:56】127.0.0.1长时间未响应,从服务器移除
【2010-03-10 14:24:49】开启服务器
【2010-03-10 14:25:50】59.175.191.118登入服务器
【2010-03-10 14:28:18】127.0.0.1登入服务器
【2010-03-10 14:28:18】127.0.0.1申请搜索,关键字 =
【2010-03-10 14:29:32】系统广播消息:test
【2010-03-10 14:29:32】系统广播消息:test
【2010-03-10 14:30:44】127.0.0.1长时间未响应,从服务器移除
【2010-03-10 14:30:53】123.118.15.209登入服务器
【2010-03-10 14:30:54】123.118.15.209申请搜索,关键字 =
这里是我的服务器日志类。
需要注意的是由于多线程写日志,需要线程互斥访问log文件,注意 is_busy 变量。
#ifndef NETSHARE_LOG_H_
#define NETSHARE_LOG_H_
#include <string>
#include <vector>
#include <fstream>
#include <ctime>
using namespace std;
//服务器日志管理类
class NS_Log
{
public:
NS_Log( string filename )
: logfile( filename.c_str(), ios::app )
, is_busy( false )
{}
~NS_Log()
{
logfile.close();
}
void Write( string dat )
{
while( is_busy ) //互斥
{
Sleep( 20 );
}
is_busy = true;
string now_time = GetNowTime();
logfile<<"【"<<now_time<<"】"<<dat<<endl;
is_busy = false;
}
private:
//获取当前时间
string GetNowTime()
{
char pTime[1000];
int year=0,mon=0,day=0,hour=0,min=0,sec=0;
time_t now_time;
now_time = time(NULL);
struct tm *m_tm;
m_tm = gmtime(&(time_t)now_time);
year = m_tm->tm_year+1900;
mon = m_tm->tm_mon+1;
day = m_tm->tm_mday;
hour = m_tm->tm_hour;
min = m_tm->tm_min;
sec = m_tm->tm_sec;
sprintf(pTime, "%04d-%02d-%02d %d:%d:%d", year, mon, day, hour, min, sec);
return string( pTime );
}
fstream logfile;
bool is_busy;
};
#endif
未完待续……
分享到:
相关推荐
本项目“基于socket的文件传输”是针对Java Socket编程的一次实战练习,旨在实现单方文件的传输功能。在这个过程中,我们将深入探讨Socket编程的核心概念、步骤以及如何应用它们来实现文件的网络传输。 Socket,...
在Linux系统中,实现基于Socket的多进程实时通信是一项重要的技术,它允许不同的进程间高效地交换数据。本文将详细介绍如何创建一个通信服务器(server)来作为中介,处理多个客户端(client)的连接和通信请求。 ...
本项目“用基于Socket做的类似资源管理器的文件共享”旨在创建一个简易的文件共享系统,其设计灵感来源于Windows资源管理器,使用户能够方便地进行文件的上传和下载,同时在操作过程中提供进度显示。 首先,Socket...
在本项目中,“QT实现的基于TCP Socket的共享白板”是一个利用QT库构建的、通过TCP Socket进行通信的多人协作工具。下面将详细介绍QT库、TCP Socket以及共享白板的相关知识点。 1. QT库: - QT库提供了一整套的C++...
为了克服这些限制,文中提出了一种基于Socket的进程间通信(IPC)消息平台的设计与实现。 #### 二、背景知识 ##### 2.1 进程间通信(IPC) 进程间通信(Inter-Process Communication,简称IPC)是指在同一台...
总结来说,Linux下的多线程并发通信基于socket实现,结合TCP/IP协议,能够高效地处理多个客户端的并发请求。开发者需要理解套接字的概念、类型以及编程原理,同时掌握多线程编程技巧,包括线程安全、线程池等,以...
基于SOCKET和多线程的应用程序间通信技术,不仅可以实现跨平台的数据通信,还能在保证数据准确性和完整性的同时,提高系统的响应速度和处理能力。通过对多线程的合理利用,可以有效地分配系统资源,优化数据处理流程...
本项目“基于Socket的多用户网络游戏”是一个典型的利用Socket实现的多人在线交互游戏,以井字游戏(Tic-Tac-Toe)为例,展示了如何通过网络连接让多个玩家在同一平台上进行实时对战。 首先,我们要理解什么是...
- **线程概念**:线程是进程中的一个执行流,同一进程内的多个线程可以并发执行,共享进程资源,提高程序并发性能。 - **创建线程**:在Linux中,可以使用`pthread_create()`函数创建新的线程,传入线程函数指针和...
Java基于Socket文件传输示例是一种常见的网络编程应用场景,主要用于实现两个网络节点间的文件共享和交换。Socket编程是Java网络通信的基础,它提供了低级别的、面向连接的、双向的数据传输通道。在这个示例中,我们...
综合以上,这个项目通过运用SOCKET实现网络通信,利用多线程提升并发处理能力,结合非阻塞模式确保服务的实时性,以及使用STL优化数据管理和算法执行,构建了一个高效且实用的远程算术运算系统。对于想要学习网络...
以上就是基于Socket的Android IPC通信的基本原理和实现步骤。通过这种方式,不同Android进程可以相互通信,实现复杂的功能,例如文件传输、实时消息推送等。但需要注意的是,Socket通信可能会消耗较多的系统资源,...
本文将深入探讨如何使用C#语言实现一个基于TCP/IP协议的多线程Socket聊天室。这个聊天室功能允许局域网内的多台计算机进行实时信息交互,虽然没有在广域网环境下测试,但在局域网内能有效工作。 首先,我们要理解...
【LabVIEW环境下的远程资源共享与DataSocket实现】 虚拟仪器技术,以其灵活性和用户自定义性,正在逐步替代传统的硬件仪器。随着互联网的普及,虚拟仪器的网络化趋势日益凸显,LabVIEW作为虚拟仪器的重要开发平台,...
SOCKET编程是一种常见的网络通信方式,它允许两个程序间进行数据传输。SOCKET是实现网络通信的基石,是计算机网络通信中最核心的技术之一。SOCKET编程主要涉及客户端和服务器端,服务器端通过SOCKET监听来自客户端的...
总结来说,这个基于Socket的聊天工具项目涵盖了网络编程的核心概念,如TCP/IP协议、Socket接口、即时通讯实现、文件传输机制和屏幕截图共享。同时,由于提供了源代码,它对于开发者而言,是一个实践和学习网络编程的...
在“基于socket并发网络通信”中,"并发"意味着服务器可以同时处理多个客户端连接。这通常有两种实现方式: 1. 多线程:每个客户端连接创建一个新的线程来处理,这样服务器可以并行地为多个客户提供服务。例如,...
要实现Web服务器和Socket服务器之间的通信,你可以创建一个共享的数据结构,如全局变量或队列,两者都可以访问。例如,Web服务器接收到一个HTTP请求,处理后将数据放入队列,Socket服务器定期检查队列并发送数据给...
Java网络编程的核心是基于Socket进行通信,Socket是TCP/IP协议栈的一种实现,它允许两个网络节点(通常是客户端和服务器)通过TCP或UDP进行数据交换。Socket接口为应用程序提供了低级别的网络通信控制,允许开发者...