(一)项目概述:
C++服务器是之前编写好的,有对应的C++客户端。因此,服务器的C++代码不能改变。主要解决的问题是:
1.如何用java类来还原服务器中的结构体
2.数据之间的转换
3.socket通信数据统一用字节数组。
(二)首先看一下服务器的代码:(360安全卫士竟然说我的代码是木马...好吧,这个服务器不就是能联网,能获取本地数据么?确实有点像木马,但绝对不是!)
/*主要功能是获得系统硬盘符号及硬盘下的目录和文件*/
[C++ code]
// FileNetServer.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "FileNetServer.h" #include <winsock.h> #include <windows.h> #include "SYS.H" #pragma comment(lib, "ws2_32") #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif typedef struct { int ID; BYTE lparam[BUF_LEN*2]; }COMMAND; /*BOOL 4byte HICON 4byte*/ typedef struct { char FileName[MAX_PATH];//260byte int FileLen; char Time[50]; BOOL IsDir; BOOL Error; HICON hIcon; }FILEINFO; BOOL DeleteDirectory(char *DirName); BOOL CapScreen(LPTSTR FileName); DWORD WINAPI SLisen(LPVOID lparam); DWORD GetDriverProc(COMMAND command, SOCKET client); DWORD GetDirInfoProc(COMMAND command, SOCKET client); DWORD ExecFileProc(COMMAND command, SOCKET client); DWORD DelFileProc(COMMAND command, SOCKET client); DWORD FileInfoProc(COMMAND command, SOCKET client); DWORD CreateDirProc(COMMAND command, SOCKET client); DWORD DelDirProc(COMMAND command, SOCKET client); DWORD GetFileProc(COMMAND command, SOCKET client); DWORD PutFileProc(COMMAND command, SOCKET client); DWORD GetScreenProc(COMMAND command, SOCKET client); ///////////////////////////////////////////////////////////////////////////// // The one and only application object CWinApp theApp; using namespace std; int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { WSADATA wsadata; SOCKET FileNetServer; SOCKET client; SOCKADDR_IN FileNetServeraddr; SOCKADDR_IN clientaddr; int port = 17329; WORD ver = MAKEWORD(2,2); WSAStartup(ver, &wsadata); FileNetServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); FileNetServeraddr.sin_family = AF_INET; FileNetServeraddr.sin_port = htons(port); FileNetServeraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); bind(FileNetServer, (SOCKADDR*)&FileNetServeraddr, sizeof(FileNetServeraddr)); listen(FileNetServer, 5); int len = sizeof(clientaddr); char s_password[100]; while(true) { if(client = accept(FileNetServer, (sockaddr*)&clientaddr, &len)) { if(send(client, "Password", sizeof("Password"), 0) != SOCKET_ERROR) { cout<<"有客户请求连接,正在等待客户输入密码!"; } ag: if(recv(client, s_password, sizeof(s_password), 0) != SOCKET_ERROR) { if(strcmp(s_password, "123") == 0) { send(client, "OK", sizeof("OK"), 0); cout<<"CreateThread is the OK \n"; CreateThread(NULL, NULL, SLisen, (LPVOID)client, NULL, NULL); } else { cout<<"有用户试图联入,但是未能输入正确密码!/n"; send(client, "NOOK", sizeof("NOOK"), 0); goto ag; } } } } closesocket(FileNetServer); closesocket(client); WSACleanup(); return 0; } DWORD WINAPI SLisen(LPVOID lparam) { SOCKET client = (SOCKET)lparam; COMMAND command; while(1) { memset((char*)&command, 0, sizeof(command)); if(recv(client, (char*)&command, sizeof(command), 0) == SOCKET_ERROR) { cout<<"The Client Socket is Closed\n"; break; } else { cout<<"The recv command is: ID="<<command.ID<<" lparam="<<command.lparam<<endl; switch(command.ID) { case GetDriver: GetDriverProc(command, client); break; case GetDirInfo: GetDirInfoProc(command, client); break; case ExecFile: ExecFileProc(command, client); break; case DelFile: DelFileProc(command, client); break; case FileInfo: FileInfoProc(command, client); break; case CreateDir: CreateDirProc(command, client); break; case DelDir: DelDirProc(command, client); break; case GetFile: GetFileProc(command, client); break; case PutFile: PutFileProc(command, client); break; case GetScreen: GetScreenProc(command, client); break; default: cout<<"Can not recongnize the command!\n"; break; } } } closesocket(client); return 0; } DWORD GetDriverProc(COMMAND command, SOCKET client) { cout<<"GetDriver is ok\n"; COMMAND cmd; memset((char *)&cmd, 0, sizeof(cmd)); cmd.ID = GetDriver; for(char i='A'; i<'Z'; i++) { char x[20] = {i, ':'}; UINT Type = GetDriveType(x); if(Type==DRIVE_FIXED || Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM) { cout<<x<<"\n"; memset((char*)cmd.lparam, 0, sizeof(cmd.lparam)); strcpy((char*)cmd.lparam, x); if(send(client, (char*)&cmd, sizeof(cmd), 0) == SOCKET_ERROR) { cout<<"Send Driver is Error\n"; } } } return 0; } DWORD GetDirInfoProc(COMMAND command, SOCKET client) { cout<<"GetDir is Ok\n"; FILEINFO fi; COMMAND cmd; memset((char*)&cmd, 0, sizeof(cmd)); memset((char*)&fi, 0, sizeof(fi)); strcat((char*)command.lparam, "*.*"); cout<<(char*)command.lparam<<"\n"; CFileFind file; BOOL bContinue = file.FindFile((char*)command.lparam); while(bContinue) { memset((char*)&cmd, 0, sizeof(cmd)); memset((char*)&fi, 0, sizeof(fi)); bContinue = file.FindNextFile(); if(file.IsDirectory()) { fi.IsDir = true; } strcpy(fi.FileName, file.GetFileName().LockBuffer()); cout<<fi.FileName<<"\n"; cmd.ID = GetDirInfo; memcpy((char*)&cmd.lparam, (char*)&fi, sizeof(fi)); if(send(client, (char*)&cmd, sizeof(cmd), 0) == SOCKET_ERROR) { cout<<"Send Dir is Error\n"; } } return 0; } DWORD ExecFileProc(COMMAND command, SOCKET client) { return 0; } DWORD DelFileProc(COMMAND command, SOCKET client) { return 0; } DWORD FileInfoProc(COMMAND command, SOCKET client) { return 0; } DWORD CreateDirProc(COMMAND command, SOCKET client) { return 0; } DWORD DelDirProc(COMMAND command, SOCKET client) { return 0; } BOOL DeleteDirectory(char *DirName) { return 0; } DWORD GetFileProc(COMMAND command, SOCKET client) { return 0; } DWORD PutFileProc(COMMAND command, SOCKET client) { return 0; } DWORD GetScreenProc(COMMAND command, SOCKET client) { return 0; } BOOL CapScreen(LPTSTR FileName) { return 0; }
(三)最主要的是客户端如何编写:
当然,编程流程和博客[http://blog.csdn.net/nuptboyzhb/article/details/8041715]是一样的。主要有一下几个类:
1.Client.java //还有main函数的类,你们都知道它是功能。
/* *@author: ZhengHaibo *web: blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2012-9-23 Nanjing njupt */ import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; public class Client { NetDataTypeTransform mNetDataTypeTransform=new NetDataTypeTransform(); private static final String IP="127.0.0.1"; private static final int NetPort=17329; private Socket sock; public Client(){ try { onCreate(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void onCreate() throws IOException{ InetSocketAddress addr = new InetSocketAddress(IP,NetPort); //创建socket sock = new Socket(); sock.connect(addr);//连接服务器 byte []receive=new byte[9]; sock.getInputStream().read(receive); String tempString=mNetDataTypeTransform.ByteArraytoString(receive, receive.length); System.out.println(" Server said:send your "+tempString); if(tempString.equals("Password")){ System.out.println("I can send password 123\0!"); } String password="123\0";//注意,别忘了‘\0’ sock.getOutputStream().write(mNetDataTypeTransform.StringToByteArray(password)); byte []isOk=new byte[3]; sock.getInputStream().read(isOk); String okString=mNetDataTypeTransform.ByteArraytoString(isOk,isOk.length); System.out.println(" ----- is ok?--"+okString); if(okString.equals("OK")){ System.out.println("new Thread begin..."); NetDataCommand commd=new NetDataCommand(1,"E:\0"); sock.getOutputStream().write(commd.getByteArrayData()); ThreadRead mThreadRead=new ThreadRead(sock,this); mThreadRead.start();//启动监听线程。 } ////////////////////////////////////////////////////////////// try { Thread.sleep(30000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void main(String [] args) throws InterruptedException, IOException { new Client(); } public void GetDriverPro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"--"+"command Lparam="+mCommand.getLparam()); NetDataCommand commd=new NetDataCommand(2,mCommand.getLparam()+"\\\0"); try { mSocket.getOutputStream().write(commd.getByteArrayData()); } catch (IOException e){ // TODO Auto-generated catch block e.printStackTrace(); } } public void GetDirInfoPro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void ExecFilePro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void DelFilePro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void FileInfoPro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void CreateDirPro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void GetFilePro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void PutFilePro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } public void GetScreenPro(Socket mSocket,NetDataCommand mCommand){ System.out.println("command ID="+mCommand.getID()+"command Lparam="+mCommand.getLparam()); } }
2.NetDataTypeTransform.java//顾名思义:数据转换的类
import java.io.UnsupportedEncodingException; /* *@author: ZhengHaibo *web: blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2012-9-25 Nanjing njupt */ public class NetDataTypeTransform { public NetDataTypeTransform(){ } /** * 将int转为低字节在前,高字节在后的byte数组 */ public byte[] IntToByteArray(int n) { byte[] b = new byte[4]; b[0] = (byte) (n & 0xff); b[1] = (byte) (n >> 8 & 0xff); b[2] = (byte) (n >> 16 & 0xff); b[3] = (byte) (n >> 24 & 0xff); return b; } /** * byte数组转化为int * 将低字节在前转为int,高字节在后的byte数组 */ public int ByteArrayToInt(byte[] bArr) { int n = 0; for(int i=0;i<bArr.length&&i<4;i++){ int left = i*8; n+= (bArr[i] << left); } return n; } /** * 将byte数组转化成String */ public String ByteArraytoString(byte[] valArr,int maxLen) { String result=null; int index = 0; while(index < valArr.length && index < maxLen) { if(valArr[index] == 0) { break; } index++; } byte[] temp = new byte[index]; System.arraycopy(valArr, 0, temp, 0, index); try { result= new String(temp,"GBK"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } public byte[] StringToByteArray(String str){ byte[] temp = null; try { temp = str.getBytes("GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return temp; } }
3.NetDataCommand.java//该类就是实现与C++服务器中COMMMAND结构体对应的java类
/* *@author: ZhengHaibo *web: blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2012-9-26 Nanjing njupt */ public class NetDataCommand { private static final int IDLen=4; private static final int LparamLen=2048; private static final int CommandLen=2052; public byte []byteArrayData=new byte[CommandLen]; private int ID; private String lparam; private NetDataTypeTransform mDataTypeTransform=new NetDataTypeTransform();; public byte[] getByteArrayData(){ return byteArrayData; } public NetDataCommand(){ } public NetDataCommand(int ID,String lparam) { // TODO Auto-generated constructor stub this.ID=ID; this.lparam=lparam; byte[] IDbyte = mDataTypeTransform.IntToByteArray(ID); System.arraycopy(IDbyte,0, byteArrayData, 0, IDbyte.length); byte[] Strbyte = mDataTypeTransform.StringToByteArray(lparam); System.arraycopy(Strbyte,0,byteArrayData,IDbyte.length,Strbyte.length); } public NetDataCommand(byte[] dataArray){ int id=1; String lpString=""; System.arraycopy(dataArray,0, byteArrayData,0,CommandLen); byte[] forIntID = new byte[IDLen]; System.arraycopy(dataArray,0,forIntID,0,forIntID.length); id=mDataTypeTransform.ByteArrayToInt(forIntID); byte[] StrTemp=new byte[LparamLen]; System.arraycopy(dataArray,IDLen,StrTemp,0,StrTemp.length); lpString=mDataTypeTransform.ByteArraytoString(StrTemp, StrTemp.length); //lpString=StrTemp.toString(); ID=id; lparam=lpString; } public int getID(){ return ID; } public String getLparam(){ return lparam; } public void setID(int id) { this.ID=id; } public void setLparam(String str){ this.lparam=str; } }
4.ThreadRead.java//线程,用于一直接收数据。
/* *@author: ZhengHaibo *web: blog.csdn.net/nuptboyzhb *mail: zhb931706659@126.com *2012-9-26 Nanjing njupt */ import java.io.IOException; import java.lang.Thread; import java.net.Socket; public class ThreadRead extends Thread{ public Socket mSocket; public Client mClient; private static final int GetDriver=0x01; private static final int GetDirInfo=0x02; private static final int ExecFile=0x03; private static final int GetFile=0x04; private static final int PutFile=0x05; private static final int DelFile=0x06; private static final int DelDir =0x07; private static final int CreateDir=0x08; private static final int FileInfo=0x09; private static final int GetScreen=0x10; private static final int CommandLen=2052; private static int TryTimes=5; private byte []byteArrayData=new byte[CommandLen]; public ThreadRead(Socket lpSocket,Client mClient) { // TODO Auto-generated constructor stub this.mSocket=lpSocket; this.mClient=mClient; } public void run() { while (TryTimes>0) { while (true) { try { mSocket.getInputStream().read(byteArrayData); NetDataCommand mCommand = new NetDataCommand(byteArrayData); switch (mCommand.getID()){ case GetDriver: mClient.GetDriverPro(mSocket, mCommand); break; case GetDirInfo: mClient.GetDirInfoPro(mSocket, mCommand); break; case ExecFile: mClient.ExecFilePro(mSocket, mCommand); break; case DelFile: mClient.DelFilePro(mSocket, mCommand); break; case FileInfo: mClient.FileInfoPro(mSocket, mCommand); break; case CreateDir: mClient.CreateDirPro(mSocket, mCommand); break; case DelDir: mClient.DelFilePro(mSocket, mCommand); break; case GetFile: mClient.GetFilePro(mSocket, mCommand); break; case PutFile: mClient.PutFilePro(mSocket, mCommand); break; case GetScreen: mClient.GetScreenPro(mSocket, mCommand); break; default: System.out.println("----------wrong!!!--------------"); break; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); TryTimes--; break; } } } } }
(四)实现结果
项目源码:http://download.csdn.net/detail/nuptboyzhb/4624574
先运行服务器,再运行java客户端代码。实验结果如下:(当然,这是我电脑下的文件夹和文件(隐私暴漏了...))
运行服务器的时候,我真的想告诉360安全卫士,这不是木马...
Eclipse的控制台:
Server said:send your Password I can send password 123 ----- is ok?--OK new Thread begin... command ID=1--command Lparam=C: command ID=1--command Lparam=D: command ID=1--command Lparam=E: command ID=1--command Lparam=F: command ID=1--command Lparam=G: command ID=2command Lparam=$Recycle.Bin command ID=2command Lparam=.rnd command ID=2command Lparam=360Rec command ID=2command Lparam=360SANDBOX command ID=2command Lparam=9c3e42423a202668d396d3be5e command ID=2command Lparam=autoexec.bat command ID=2command Lparam=bar.emf command ID=2command Lparam=config.sys command ID=2command Lparam=cygwin command ID=2command Lparam=Documents and Settings command ID=2command Lparam=hiberfil.sys command ID=2command Lparam=IO.SYS command ID=2command Lparam=MSDOS.SYS command ID=2command Lparam=MSOCache command ID=2command Lparam=pagefile.sys command ID=2command Lparam=PerfLogs command ID=2command Lparam=Program Files command ID=2command Lparam=ProgramData command ID=2command Lparam=Recovery command ID=2command Lparam=System Volume Information command ID=2command Lparam=Users command ID=2command Lparam=Windows command ID=2command Lparam=$RECYCLE.BIN command ID=2command Lparam=eclipse command ID=2command Lparam=HelloJNI command ID=2command Lparam=System Volume Information command ID=2command Lparam=大学部分资料 command ID=2command Lparam=文件鱼龙混杂 command ID=2command Lparam=照片和视频 command ID=2command Lparam=研究方向 command ID=2command Lparam=研究生学习 command ID=2command Lparam=程序语言 command ID=2command Lparam=软件安装包 command ID=2command Lparam=$RECYCLE.BIN command ID=2command Lparam=360 command ID=2command Lparam=360Downloads command ID=2command Lparam=360Rec command ID=2command Lparam=360云盘 command ID=2command Lparam=360驱动大师目录 command ID=2command Lparam=61ffd6de5ad141016097 command ID=2command Lparam=android-sdk-windows command ID=2command Lparam=CSDN_ExportBlog command ID=2command Lparam=eclipse command ID=2command Lparam=EditPlus command ID=2command Lparam=Fetion2012 command ID=2command Lparam=FlashFXP_4.2.4.1785 command ID=2command Lparam=JDK1_6 command ID=2command Lparam=kankan command ID=2command Lparam=KMPlayer command ID=2command Lparam=KSafeRecycle command ID=2command Lparam=Kugou command ID=2command Lparam=KuGouCache command ID=2command Lparam=matlab2009a command ID=2command Lparam=msdn6_0 command ID=2command Lparam=MSOCache command ID=2command Lparam=MySQL Tools command ID=2command Lparam=PDF_Reader command ID=2command Lparam=PHPEclipse command ID=2command Lparam=Program Files command ID=2command Lparam=ps3 command ID=2command Lparam=Python27 command ID=2command Lparam=QQ command ID=2command Lparam=QQGame command ID=2command Lparam=sogou command ID=2command Lparam=System Volume Information command ID=2command Lparam=TDDOWNLOAD command ID=2command Lparam=Ubuntu command ID=2command Lparam=vc2008 command ID=2command Lparam=vc6_0 command ID=2command Lparam=VC98 command ID=2command Lparam=Video command ID=2command Lparam=VMware command ID=2command Lparam=WAMP5 command ID=2command Lparam=WindowsManagerTools command ID=2command Lparam=youku command ID=2command Lparam=光影看看 command ID=2command Lparam=快捷方式 command ID=2command Lparam=有道 command ID=2command Lparam=迅雷7
服务器的显示:
原文链接: http://blog.csdn.net/nuptboyzhb/article/details/8047619