TCP传输中使用AES加密和gizp压缩(2)--封装TcpUtil,封装后实现登陆
一、TcpUtil
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283/**
*@authorqiwenming
*@time2015年5月31日上午4:24:02
*@说明TcpUtil
*/
public
class
TcpUtil{
private
OutputStreamoutputStream;
private
InputStreaminputStream;
private
Socketsocket;
private
ProgressDialogpd;
//进度提示框
private
StringTAG=TcpUtil.
class
.getName();
/**
*实体类转为json
*
*@parambeanClass
*@return
*/
public
<T>StringgetSendData(TbeanClass){
if
(beanClass==
null
){
return
""
;
}
Tbean=beanClass;
Gsongson=
new
Gson();
Stringstr=gson.toJson(bean);
return
str;
}
/**
*拼接请求字符串
*
*@parambeanClass
*@paramserverName
*@return
*/
public
<T>StringgetRequestString(TbeanClass,StringserverName){
StringBuildersb=
new
StringBuilder();
sb.append(
"{"
);
//header拼装
sb.append(
"\"header\":{"
);
sb.append(
"\"service_name\":\""
+serverName+
"\""
);
sb.append(
"},"
);
//body拼装
sb.append(
"\"body\":"
);
sb.append(getSendData(beanClass));
sb.append(
"}"
);
return
sb.toString();
}
/**
*@paramcontext
*@paramMessage
*提示框信息
*@paramisShowDialog
*是否显示提示框
*@paramcallBack
*回调
*@parambeanClass
*@paramserviceName
*调用的服务器名
*/
public
<T>
void
requestData(
final
Contextcontext,
final
Stringmessage,
boolean
isShowDialog,
final
TcpRequsetCallBackcallBack,
TbeanClass,StringserviceName){
//创建一个AsyncTask去这行请求为什么
new
MyTast<T>(context,message,isShowDialog,callBack,beanClass,serviceName).execute(
""
);
}
/**
*发送请求数据
*
*@paramrequestStr
*请求数据
*@throwsException
*异常
*/
public
void
send(StringrequestStr)
throws
Exception{
if
(outputStream==
null
){
outputStream=socket.getOutputStream();
}
//编码
byte
[]encryptBytes=AESUtil.encrypt(requestStr.getBytes());
//压缩
byte
[]compressBytes=GZipUtils.compress(encryptBytes);
//写入数据流操作
DataOutputStreamdos=
new
DataOutputStream(outputStream);
dos.writeInt(compressBytes.length);
dos.write(compressBytes);
}
/**
*接收数据
*
*@return服务器返回的字符数据
*@throwsException
*/
public
Stringreceive()
throws
Exception{
if
(inputStream==
null
){
inputStream=socket.getInputStream();
}
//获取输入流读取服务端传递过来的流
DataInputStreamdin=
new
DataInputStream(inputStream);
int
availableLen=din.readInt();
//阻塞方法
byte
[]data=receiveBytes(din,availableLen);
//读取字节数据
byte
[]uncompress=GZipUtils.decompress(data);
byte
[]decrypt=AESUtil.decrypt(uncompress);
return
new
String(decrypt,
"UTF-8"
);
}
/**
*得到接收的byte数组数据
*
*@paramis
*输入流(服务端传递过来的数据)
*@paramlength
*读取的长度
*@return字节数组
*@throwsIOException
*/
private
byte
[]receiveBytes(InputStreamis,
int
length)
throws
IOException{
int
tmpLength=
1024
;
//每次读取最大缓冲区大小
byte
[]ret=
new
byte
[length];
int
readed=
0
,offset=
0
,left=length;
byte
[]bs=
new
byte
[tmpLength];
while
(left>
0
){
try
{
//读取数据到bs数据中,读取的长度返回到readed中
readed=is.read(bs,
0
,Math.min(tmpLength,left));
if
(readed==-
1
)
//读取结束
break
;
System.arraycopy(bs,
0
,ret,offset,readed);
//copy数据
}
finally
{
offset+=readed;
//更新读取的位置
left-=readed;
//读取的长度减小
}
}
return
ret;
}
/**
*关闭流
*
*@throwsIOException
*/
public
void
disconnect()
throws
IOException{
if
(outputStream!=
null
){
outputStream.close();
}
if
(inputStream!=
null
){
inputStream.close();
}
if
(socket!=
null
&&!socket.isClosed()){
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
}
}
/**
*@authorqiwenming
*@param<T>
*@creation2015-5-19下午3:39:56
*@instruction网络请求(参数,进度,结果)
*/
class
MyTast<T>
extends
AsyncTask<String,Integer,NetResponse>{
private
Contextcontext;
private
Stringmessage;
private
boolean
isShowDialog;
private
TcpRequsetCallBackcallBack;
private
TbeanClass;
private
StringserviceName;
public
MyTast(
final
Contextcontext,
final
Stringmessage,
boolean
isShowDialog,TcpRequsetCallBackcallBack,TbeanClass,
StringserviceName){
this
.context=context;
this
.message=message;
this
.isShowDialog=isShowDialog;
this
.callBack=callBack;
this
.beanClass=beanClass;
this
.serviceName=serviceName;
}
/**
*请求数据前
*/
protected
void
onPreExecute(){
if
(!ConnectUtils.isNetworkConnected(context)){
Toast.makeText(context,
"网络未连接,请检查网络"
,
0
).show();
return
;
}
if
(isShowDialog){
//判断是否需要显示dialog
pd=
new
ProgressDialog(context);
if
(
this
.message==
null
){
//判断要显示的文字
pd.setMessage(
"正在加载数据"
);
}
else
{
pd.setMessage(message);
}
pd.show();
}
}
/**
*请求数据中
*/
protected
NetResponsedoInBackground(String...params){
NetResponsenrp=
new
NetResponse();
try
{
socket=
new
Socket(
"192.168.1.106"
,
8888
);
socket.setSoTimeout(
10
*
1000
);
//这里不使用params使用他会加[]所以不用
StringrequestMsg=getRequestString(beanClass,serviceName);
if
(MyApplication.isShowLog){
//如果需要打印日志的话打印数据
Log.i(serviceName,
"请求数据###"
+requestMsg);
}
send(requestMsg);
StringrespMsg=receive();
//接收数据
nrp.status=ResponseStatus.OK;
nrp.responseMsg=respMsg;
if
(MyApplication.isShowLog){
//如果需要打印日志的话打印数据
Log.i(serviceName,
"响应数据"
+respMsg);
}
}
catch
(IOExceptione){
nrp.status=ResponseStatus.ERR;
nrp.responseMsg=TAG+
"---doInBackground():IOException:请求或者接收数据时候出问题"
;
nrp.exception=e;
//e.printStackTrace();
}
catch
(Exceptione){
nrp.status=ResponseStatus.ERR;
nrp.responseMsg=TAG+
"---doInBackground():IOException:请求或者接收数据时候出问题"
;
nrp.exception=e;
//e.printStackTrace();
}
finally
{
//关闭对话框
if
(pd!=
null
&&pd.isShowing()){
pd.dismiss();
}
try
{
if
(socket!=
null
&&!socket.isClosed()){
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
socket=
null
;
}
if
(outputStream!=
null
){
outputStream.close();
}
if
(inputStream!=
null
){
inputStream.close();
}
}
catch
(IOExceptione){
//关闭流除了问题
//e.printStackTrace();
nrp.status=ResponseStatus.ERR;
nrp.responseMsg=TAG+
"---doInBackground():IOException:关闭流除了问题"
;
nrp.exception=e;
// callBack.onErr(nrp);
}
}
return
nrp;
}
/**
*请求数据结束后
*/
protected
void
onPostExecute(NetResponseresult){
if
(ResponseStatus.OK==result.status){
//请求成功
callBack.onRequestSuccess(result.responseMsg);
}
else
{
//请求失败
callBack.onErr(result);
}
}
}
}
TcpRequsetCallBack
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970/**
*@authorqiwenming
*@time2015年5月30日下午11:35:41
*@说明Tcp请求的回调类
*/
public
abstract
class
TcpRequsetCallBack<TR>{
// privateBaseRspBean<TR>baseRsp;
private
Class<TR>beanClass;
private
StringTAG=TcpRequsetCallBack.
class
.getName();
/**
*构造函数
*@param<TR>
*@parambeanClass
*/
public
TcpRequsetCallBack(Class<TR>beanClass){
this
.beanClass=beanClass;
}
/**
*请求成功的方法
*@paramresponseMsg
*/
public
<T>
void
onRequestSuccess(StringresponseMsg){
Gsongson=
new
Gson();
try
{
TRbean=gson.fromJson(responseMsg,beanClass);
if
(bean
instanceof
BaseRespBean){
BaseRespBeanbnBean=(BaseRespBean)bean;
if
(!
"0000"
.equals(bnBean.result_code)){
//这里的判断根据规定的响应码来判断
onfail(bnBean.result_code,bnBean.result_msg);
return
;
}
onSuccess(bean);
}
}
catch
(JsonSyntaxExceptione){
NetResponsenetRspJson=
new
NetResponse();
netRspJson.exception=e;
netRspJson.responseMsg=TAG+
":onRequestSuccess():JsonSyntaxException:响应数据转换json的时候处理问题"
;
onErr(netRspJson);
}
};
/**
*得到正确的数据
*@paramheader
*@paramresultMsg
*@paramresultCode
*/
public
abstract
void
onSuccess(TRbean);
/**
*数据错误
*@paramfailDesc错误信息
*@paramresult_code错误码
*/
public
void
onfail(Stringresult_code,StringfailDesc){
Log.e(TAG+
".onfail"
,
"请求数据失败:result_code:"
+result_code+
"failDesc:"
+failDesc);
};
/**
*请求报错
*@paramnetQuest
*/
public
void
onErr(NetResponsenetRsp){
Log.e(TAG+
".onErr"
,netRsp.responseMsg);
netRsp.exception.printStackTrace();
};
}
BaseRespBean
123456789/**
*@authorqiwenming
*@time2015年5月31日上午12:11:18
*@说明响应基类
*/
public
class
BaseRespBean
implements
Serializable{
public
Stringresult_code;
public
Stringresult_msg;
}
1.LoginReqBean
2.BaseRespBean
123456789/**
*@authorqiwenming
*@time2015年5月30日下午11:57:40
*@说明登陸請求的javabean
*/
public
class
LoginReqBean
implements
Serializable{
public
Stringusername;
public
Stringpassword;
}
123456789/**
*@authorqiwenming
*@time2015年5月31日上午12:11:18
*@说明响应基类
*/
public
class
BaseRespBean
implements
Serializable{
public
Stringresult_code;
public
Stringresult_msg;
}
3.LoginRespBean
12345678910111213/**
*@authorqiwenming
*@time2015年5月31日上午12:10:41
*@说明登陆响应类
*/
public
class
LoginRespBean
extends
BaseRespBean{
public
LoginDatadata;
public
class
LoginData
implements
Serializable{
public
StringnickName;
public
int
age;
}
}
三、登陆中客户端登陆方法
1234567891011121314151617181920212223242526272829303132333435363738/**
*登陆
*
*@paramv
*/
public
void
toLogin(Viewv){
Stringname=nameEdt.getText().toString().trim();
Stringpwd=pwdEdt.getText().toString().trim();
if
(
""
.equals(name)){
Toast.makeText(
this
,
"用户名为空"
,
0
).show();
return
;
}
if
(
""
.equals(name)){
Toast.makeText(
this
,
"密码为空"
,
0
).show();
return
;
}
LoginReqBeanbean=
new
LoginReqBean();
bean.username=name;
bean.password=pwd;
new
TcpUtil().requestData(
this
,
"登陆请求中..."
,
true
,
new
TcpRequsetCallBack<LoginRespBean>(LoginRespBean.
class
){
@Override
public
void
onSuccess(LoginRespBeanbean){
//登陆成功
Intenti=
new
Intent(MainActivity.
this
,HomeActivity.
class
);
i.putExtra(
"loginbean"
,bean);
startActivity(i);
MainActivity.
this
.finish();
}
@Override
public
void
onfail(Stringresult_code,StringfailDesc){
//登陆失败
super
.onfail(result_code,failDesc);
Toast.makeText(MainActivity.
this
,result_code+
":"
+failDesc,
0
).show();
}
},bean,
"loginServer"
);
}
四、java控制台程序模拟的后台主要方法
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127/**
*@authorxiaoming
*@time2015年5月30日下午5:01:01
*@说明AesDemo
*/
public
class
AesDemo{
public
static
void
main(String[]args){
test();
}
public
static
void
test(){
ServerSocketss=
null
;
try
{
ss=
new
ServerSocket(
8888
);
while
(
true
){
final
Sockets=ss.accept();
new
Thread(
new
Runnable(){
public
void
run(){
try
{
DataInputStreamdis=
new
DataInputStream(
s.getInputStream());
//读取数据
byte
[]recData=(
new
TcpUtil()).readData(dis);
System.out.println(
"长度:"
+recData.length);
////解压缩
byte
[]uncompress=GZipUtils.decompress(recData);
//解密
byte
[]decrypt=AESUtil.decrypt(uncompress);
//======================响应部分================================
DataOutputStreamdos=
new
DataOutputStream(
s.getOutputStream());
byte
[]respData=handlerData(decrypt);
//加密
byte
[]encrypt=AESUtil.encrypt(respData);
////压缩
byte
[]compress=GZipUtils.compress(encrypt);
dos.writeInt(compress.length);
//把数据的长度写过去
dos.write(compress);
dos.flush();
s.shutdownOutput();
}
catch
(InvalidCipherTextExceptione){
e.printStackTrace();
}
catch
(IOExceptione){
e.printStackTrace();
}
catch
(Exceptione){
e.printStackTrace();
}
}
}).start();
}
}
catch
(Exceptione){
e.printStackTrace();
}
finally
{
try
{
//关闭资源
if
(ss!=
null
){
ss.close();
}
}
catch
(IOExceptione){
e.printStackTrace();
}
}
}
/**
*实体类转为json
*
*@parambeanClass
*@return
*/
public
static
<T>StringgetSendData(TbeanClass){
if
(beanClass==
null
){
return
""
;
}
Tbean=beanClass;
Gsongson=
new
Gson();
Stringstr=gson.toJson(bean);
return
str;
}
/**
*处理数据
*/
public
static
byte
[]handlerData(
byte
[]decrypt){
StringreqMsg=
new
String(decrypt);
System.out.println(
"请求的数据:"
+reqMsg);
Gsongson=
new
Gson();
//获得数据
LoginReqBeanbean=gson.fromJson(reqMsg,LoginReqBean.
class
);
LoginRespBeanrespBean=
new
LoginRespBean();
if
(
null
!=bean){
if
(
"loginServer"
.equals(bean.header.service_name)){
if
(
"xiaoming"
.equals(bean.body.username)){
if
(
"520"
.equals(bean.body.password)){
respBean.result_code=
"0000"
;
respBean.result_msg=
"登陆成功"
;
respBean.data.nickName=
"小明"
;
respBean.data.age=
24
;
}
else
{
respBean.data=
null
;
respBean.result_code=
"1001"
;
respBean.result_msg=
"密码错误"
;
}
}
else
{
respBean.data=
null
;
respBean.result_code=
"1002"
;
respBean.result_msg=
"用户名错误"
;
}
}
else
{
respBean.data=
null
;
respBean.result_code=
"1003"
;
respBean.result_msg=
"没有这个服务名"
;
}
}
else
{
respBean.data=
null
;
respBean.result_code=
"1004"
;
respBean.result_msg=
"数据为空"
;
}
StringrespMsg=getSendData(respBean);
System.out.println(
"响应的数据:"
+respMsg);
return
respMsg.getBytes();
}
}