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

长平狐 发布于 2012/10/08 15:24
阅读 3K+
收藏 0

(一)项目概述:
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
加载中
返回顶部
顶部