界面用的Qt做的,制作的是一个小工具,实在是没时间,代码只是初步代码,很多Bug,估计还不能完美运行起来了。开始打算增加个内网穿透模块的,一来找不到服务器,二来工作上上最近换新框架,真的抽不出时间来,每天下班都比较累,想听下音乐放松下就洗洗睡了,各位不要见笑。
下面上代码。初步模型呢,画了个图,方便理解,都是小东西,select是过时的东西了,并不适合真正的项目了。

代码如下:
Server:
Server.h
class ServerInit
{
public:
ServerInit(void);
~ServerInit(void);
void Init();
void CheckPackType(SOCKET *_socket);
void AddFileinfo(DataInfo _datainfo,SOCKET *_sock);
void SendInfo(SOCKET _sock,ServerInit *pServer);
void ClientRegister(DataInfo *_pdata,SOCKET *_sock);
FD_SET * GetFD(){return &m_fd;}
SOCKET* GetSocket(){return &m_ServerSock;}
std::map<char*,ServerInfo>* GetMap(){return &m_ClientData;}
std::map<SOCKET,sockaddr_in> m_clientIP;
private:
SOCKET m_ServerSock;
WSADATA m_ServerData;
SOCKADDR_IN m_ServerADDR;
SOCKET m_acceptClient;
HANDLE m_handle;
DWORD m_ThreadID;
FD_SET m_fd;
std::map<char*,ServerInfo>m_ClientData;
};
Server.cpp
#include "stdafx.h"
#include "ServerInit.h"
timeval g_timeout = {1,0}; //2s轮询
ServerInit::ServerInit(void)
{
#ifdef WIN32
int errorValue = WSAStartup(MAKEWORD(2,2),&m_ServerData);
if (errorValue != NO_ERROR)
{
printf("Init Error,Get Version Error");
return;
}
if(LOBYTE(m_ServerData.wVersion)!=2 || HIBYTE(m_ServerData.wVersion)!=2)
{
printf("Error,网络初始化错误");
return ;
}
#endif
m_ServerSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_ServerSock == INVALID_SOCKET)
{
return;
}
m_ServerADDR.sin_family = AF_INET;
m_ServerADDR.sin_addr.S_un.S_addr =INADDR_ANY;
m_ServerADDR.sin_port = htons(SERVER_PORT);
if(bind(m_ServerSock,(sockaddr*)&m_ServerADDR,sizeof(m_ServerADDR))<0)
{
return ;
}
listen(m_ServerSock,20);
FD_ZERO(&m_fd);
FD_SET(m_ServerSock,&m_fd);
}
ServerInit::~ServerInit(void)
{
}
//检测包的类型
void ServerInit::CheckPackType(SOCKET *_socket)
{
DataInfo *buff = new DataInfo;
recv(*_socket,(char*)buff,g_Packlength,NULL);
switch (buff->id)
{
case IsRegister: ClientRegister(buff,_socket);break;
case SEARCHDATA: SendInfo(_sock,pServer);break;
case sendFileInfo: AddFileinfo(pdata,_sock);
default:
printf("错误的数据类型== %d",pdata.id);
break;
}
}
void ServerInit::ClientRegister(DataInfo *_pdata,SOCKET *_sock)
{
DataInfo RegisterInfo;
std::map<SOCKET,sockaddr_in>::iterator _clientinfo = m_clientIP.find(*_sock);
assert(_clientinfo != m_clientIP.end());
char* clientIP = inet_ntoa(_clientinfo->second.sin_addr);
std::map<char*,ServerInfo>::iterator _iter = m_ClientData.find(clientIP);
if (_iter == m_ClientData.end())
{
printf("新的用户,%s",clientIP);
RegisterInfo.id = UnKnowClient;
send(*_sock,(char*)&RegisterInfo,sizeof(DataInfo),NULL);
}
else
{
RegisterInfo.id = KnowClient;
send(*_sock,(char*)&RegisterInfo,sizeof(DataInfo),NULL);
}
}
void ServerInit::SendInfo(SOCKET _sock,ServerInit *pServer)
{
std::map<char*,ServerInfo>::iterator _iter = pServer->m_ClientData.begin();
DataInfo _datainfo;
for (;_iter != pServer->m_ClientData.end();_iter++)
{
auto _piter = _iter->second.m_info.begin();
for (;_piter != _iter->second.m_info.end();_piter++ )
{
_datainfo = *_piter;
send(_sock,(char*)&_datainfo,sizeof(DataInfo),NULL);
_datainfo.Reset();
}
}
}
void ServerInit::AddFileinfo(DataInfo _datainfo,SOCKET *_sock)
{
ServerInfo _Sinfo;
std::map<SOCKET,sockaddr_in>::iterator itet = m_clientIP.find(*_sock);
if (itet == m_clientIP.end())
{
assert(false);
}
_Sinfo.ip = inet_ntoa(itet->second.sin_addr);
_Sinfo.port = ntohs(itet->second.sin_port);
_Sinfo.m_info.push_back(_datainfo);
m_ClientData.insert(std::make_pair(_Sinfo.ip,_Sinfo));
}
main:
int g_state;
static void ThreadNew(LPVOID lparam)
{
ServerInit *pData =(ServerInit*)&lparam;
sockaddr_in clientinfo;
int len = sizeof(sockaddr_in);
SOCKET NewClient = accept(*pData->GetSocket(),(sockaddr*)&clientinfo,&len);
FD_SET(NewClient,pData->GetFD());
pData->m_clientIP.insert(std::make_pair(NewClient,clientinfo));
_endthread();
}
int _tmain(int argc, _TCHAR* argv[])
{
ServerInit app;
while(true)
{
FD_SET fd_read = *app.GetFD();
g_state =select(*app.GetSocket()+1,&fd_read,NULL,NULL,NULL);
if(g_state > 0)
{
for (int i = 0; i<app.GetFD()->fd_count;i++)
{
if (FD_ISSET(app.GetFD()->fd_array[i],&fd_read))
{
if (app.GetFD()->fd_array[i] == *app.GetSocket())
{
_beginthread(ThreadNew,NULL,(void*)&app);
}
else
{
app.CheckPackType((&)app.GetFD()->fd_array[i]);
}
}
}
}
if (g_state == -1)
{
int erron = WSAGetLastError();
return -1;
}
}
return 0;
}
Client:
client.h
class SockGUIThread : public QMainWindow
{
Q_OBJECT
public:
SockGUIThread(QWidget *parent = 0);
~SockGUIThread();
int InitClient();
int Register();
public slots:
void Search();
private:
Ui::SockGUIThreadClass ui;
SOCKET m_sock;
WSADATA m_data;
int m_errorValue;
SOCKADDR_IN addclient;
char Type[1]; //请求搜索的类型
DataInfo m_recvinfo;
};
client.cpp
SockGUIThread::SockGUIThread(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
ui.m_Search->setEnabled(false);
ui.m_progressBar->setMaximum(100);
ui.m_progressBar->setMinimum(0);
QObject::connect(ui.m_Search,SIGNAL(clicked()),this,SLOT(Search()));
QObject:;connect(ui.m_close,SIGNAL(clicked()),this,SLOT(close()));
Type[0]=1;
if ( InitClient() < 0 )
{
QMessageBox::about(this,"Error","初始化失败,请尝试用管理员权限运行此程序");
closesocket(m_sock);
WSACleanup();
// close();
}
}
SockGUIThread::~SockGUIThread()
{
closesocket(m_sock);
WSACleanup();
}
//第一次安装客户端,提交客户端文件信息
int SockGUIThread::InitClient()
{
m_errorValue = WSAStartup(MAKEWORD(2,2),&m_data);
if (m_errorValue != NO_ERROR)
{
QMessageBox::about(this,"Error","初始化网络错误13001");
return -1;
}
if(LOBYTE(m_data.wVersion)!=2 || HIBYTE(m_data.wVersion)!=2)
{
QMessageBox::about(this,"Error","网络初始化错误13003");
return -1;
}
m_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(m_sock == INVALID_SOCKET)
{
QMessageBox::about(this,"Error","初始化网络出错13002");
return -1;
}
addclient.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);
addclient.sin_family = AF_INET;
addclient.sin_port = htons(SERVER_PORT);
if (::connect(m_sock,(LPSOCKADDR)&addclient,sizeof(addclient)) < 0 )
{
QMessageBox::about(this,"Error","连接到服务器失败 初始化");
return -1;
}
DataInfo req;
req.id = IsRegister;
send(m_sock,(char*)&req,g_Packlength("test"),0);
req.Reset();
recv(m_sock,(char*)&req,g_Packlength("test"),0);
if(req.id == UnKnowClient)
{
Register();
}
if(req.id == KnowClient)
{
ui.m_Search->setEnabled(true);
}
return 1;
}
int SockGUIThread::Register()
{
DataInfo req;
QString CurPath;
QDir dir;
CurPath = dir.currentPath();
QStringList _StringList;
_StringList <<QString("*.jpeg")<<QString("*.png")<<QString("*.jpg")<<QString("*.bmp")<<QString("*.rmvb")<<QString("*.avi")<<QString("*.mp4");
dir.setFilter(QDir::Files | QDir::NoSymLinks);
dir.setNameFilters(_StringList);
int fileCount = dir.count();
if(dir.count() == 0)
{
return EmptyFileter;
}
CurPath = dir.currentPath();
QChar _char = QChar('\');
QStringList filelist;
for (int i=0;i<dir.count();i++)
{
QString file_name = dir[i];
filelist.append(dir.currentPath() + _char + file_name);
}
_StringList.clear();
_StringList<<"Name"<<"Size";
ui.m_tableWidget->setColumnCount(2);
// ui.m_tableWidget->setRowCount(filelist.count());
FileInfo _info;
for (int i=0;i < filelist.count();i++)
{
/* ui.m_tableWidget->setItem(i,0,new QTableWidgetItem(filelist[i]));*/
QFile _file(filelist[i]);
req.id = sendFileInfo;
req.filesize = _file.size();
req.pName =(char*)&filelist[i];
send(m_sock,(char*)&req,g_Packlength(req.pName),NULL);
req.Reset();
/* ui.m_tableWidget->setItem(i,1,new QTableWidgetItem(QString::number((float)_file.size()/1000)+"kb"));*/
}
ui.m_Search->setEnabled(true);
return 1;
}
void SockGUIThread::Search()
{
DataInfo m_recvinfo;
m_recvinfo.Reset();
m_recvinfo.id =SEARCHDATA;
send(m_sock,(char *)&m_recvinfo,g_Packlength(m_recvinfo.pName),0);
m_recvinfo.Reset();
int GetLen = recv(m_sock,(char*)&m_recvinfo,4096,0);
int _Count = ui.m_tableWidget->rowCount();
ui.m_tableWidget->setItem(_Count+1,0,new QTableWidgetItem(m_recvinfo.pName));
ui.m_tableWidget->setItem(_Count+1,1,new QTableWidgetItem(QString::number((float)m_recvinfo.filesize/(10*6))+"Mb"));
}
DataInfo.h
#include <list>
#include <map>
#include <memory.h>
#define MAX_ARRAY 1024
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 5656
#define KnowClient 1
#define UnKnowClient 3
#define IsRegister 2
#define RequestFileInfo 10
#define sendFileInfo 11
#define EmptyFileter 20
#define SEND_ERROR -5
#define SEARCHDATA 30
struct FileInfo
{
long filesize;
char *pName;
};
//连接服务端数据类型
struct DataInfo
{
int id; //id 请求类型
long filesize;
char *pName;
void Reset()
{
id =NULL;
filesize =NULL;
pName =NULL;
}
};
struct ServerInfo
{
char *ip;
int port;
std::list<DataInfo> m_info;
};
#define g_Packlength(str) (sizeof(DataInfo)+strlen(str))
