C++服务器与java进行socket通信案例

来源:互联网 发布:mac版spss许可 编辑:程序博客网 时间:2024/06/02 04:36

注:本代码版权所有!!!转载时请声明源地址:http://blog.csdn.net/nuptboyzhb/article/details/8047619

你可以学习,分享,修改,教学等。但是不得用于商业目的。目前已经发现互联网上大量与本文完全相同的文章,但是却把作者信息删除的干干净净,并且据为己有,打上某培训机构的广告!实属可恶!

最新消息:项目成品连接:http://blog.csdn.net/nuptboyzhb/article/details/8611179

(一)项目概述:
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_FILEstatic char THIS_FILE[] = __FILE__;#endiftypedef struct{int ID;BYTE lparam[BUF_LEN*2];}COMMAND;/*BOOL 4byte HICON 4byte*/typedef struct{char FileName[MAX_PATH];//260byteint 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 objectCWinApp 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 blocke.printStackTrace();}}public void onCreate() throws IOException{InetSocketAddress addr = new InetSocketAddress(IP,NetPort); //创建socketsock = 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 blocke.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 blocke.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 static final String coding="GB2312"; //全局定义,以适应系统其他部分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) {         if(bArr.length!=4){         return -1;         } return (int) ((((bArr[3] & 0xff) << 24)                  | ((bArr[2] & 0xff) << 16)                  | ((bArr[1] & 0xff) << 8) | ((bArr[0] & 0xff) << 0))); }/** * 将byte数组转化成String,为了支持中文,转化时用GBK编码方式 */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;}/** * 将String转化为byte,为了支持中文,转化时用GBK编码方式 */public byte[] StringToByteArray(String str){byte[] temp = null;    try {temp = str.getBytes("GBK");} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.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 stubthis.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 stubthis.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 blocke.printStackTrace();TryTimes--;break;}}}}}


 

(四)实现结果
项目源码:http://download.csdn.net/detail/nuptboyzhb/4624574
先运行服务器,再运行java客户端代码。实验结果如下:(当然,这是我电脑下的文件夹和文件(隐私暴漏了...))
运行服务器的时候,我真的想告诉360安全卫士,这不是木马...
Eclipse的控制台:

  Server said:send your PasswordI can send password 123----- is ok?--OKnew 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.Bincommand ID=2command Lparam=.rndcommand ID=2command Lparam=360Reccommand ID=2command Lparam=360SANDBOXcommand ID=2command Lparam=9c3e42423a202668d396d3be5ecommand ID=2command Lparam=autoexec.batcommand ID=2command Lparam=bar.emfcommand ID=2command Lparam=config.syscommand ID=2command Lparam=cygwincommand ID=2command Lparam=Documents and Settingscommand ID=2command Lparam=hiberfil.syscommand ID=2command Lparam=IO.SYScommand ID=2command Lparam=MSDOS.SYScommand ID=2command Lparam=MSOCachecommand ID=2command Lparam=pagefile.syscommand ID=2command Lparam=PerfLogscommand ID=2command Lparam=Program Filescommand ID=2command Lparam=ProgramDatacommand ID=2command Lparam=Recoverycommand ID=2command Lparam=System Volume Informationcommand ID=2command Lparam=Userscommand ID=2command Lparam=Windowscommand ID=2command Lparam=$RECYCLE.BINcommand ID=2command Lparam=eclipsecommand ID=2command Lparam=HelloJNIcommand ID=2command Lparam=System Volume Informationcommand 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.BINcommand ID=2command Lparam=360command ID=2command Lparam=360Downloadscommand ID=2command Lparam=360Reccommand ID=2command Lparam=360云盘command ID=2command Lparam=360驱动大师目录command ID=2command Lparam=61ffd6de5ad141016097command ID=2command Lparam=android-sdk-windowscommand ID=2command Lparam=CSDN_ExportBlogcommand ID=2command Lparam=eclipsecommand ID=2command Lparam=EditPluscommand ID=2command Lparam=Fetion2012command ID=2command Lparam=FlashFXP_4.2.4.1785command ID=2command Lparam=JDK1_6command ID=2command Lparam=kankancommand ID=2command Lparam=KMPlayercommand ID=2command Lparam=KSafeRecyclecommand ID=2command Lparam=Kugoucommand ID=2command Lparam=KuGouCachecommand ID=2command Lparam=matlab2009acommand ID=2command Lparam=msdn6_0command ID=2command Lparam=MSOCachecommand ID=2command Lparam=MySQL Toolscommand ID=2command Lparam=PDF_Readercommand ID=2command Lparam=PHPEclipsecommand ID=2command Lparam=Program Filescommand ID=2command Lparam=ps3command ID=2command Lparam=Python27command ID=2command Lparam=QQcommand ID=2command Lparam=QQGamecommand ID=2command Lparam=sogoucommand ID=2command Lparam=System Volume Informationcommand ID=2command Lparam=TDDOWNLOADcommand ID=2command Lparam=Ubuntucommand ID=2command Lparam=vc2008command ID=2command Lparam=vc6_0command ID=2command Lparam=VC98command ID=2command Lparam=Videocommand ID=2command Lparam=VMwarecommand ID=2command Lparam=WAMP5command ID=2command Lparam=WindowsManagerToolscommand ID=2command Lparam=youkucommand ID=2command Lparam=光影看看command ID=2command Lparam=快捷方式command ID=2command Lparam=有道command ID=2command Lparam=迅雷7


 

服务器的显示: