一、TcpUtil
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283/***@authorqiwenming*@time2015年5月31日上午4:24:02*@说明TcpUtil*/publicclassTcpUtil{privateOutputStreamoutputStream;privateInputStreaminputStream;privateSocketsocket;privateProgressDialogpd;//进度提示框privateStringTAG=TcpUtil.class.getName();/***实体类转为json**@parambeanClass*@return*/public<T>StringgetSendData(TbeanClass){if(beanClass==null){return"";}Tbean=beanClass;Gsongson=newGson();Stringstr=gson.toJson(bean);returnstr;}/***拼接请求字符串**@parambeanClass*@paramserverName*@return*/public<T>StringgetRequestString(TbeanClass,StringserverName){StringBuildersb=newStringBuilder();sb.append("{");//header拼装sb.append("\"header\":{");sb.append("\"service_name\":\""+serverName+"\"");sb.append("},");//body拼装sb.append("\"body\":");sb.append(getSendData(beanClass));sb.append("}");returnsb.toString();}/***@paramcontext*@paramMessage*提示框信息*@paramisShowDialog*是否显示提示框*@paramcallBack*回调*@parambeanClass*@paramserviceName*调用的服务器名*/public<T>voidrequestData(finalContextcontext,finalStringmessage,booleanisShowDialog,finalTcpRequsetCallBackcallBack,TbeanClass,StringserviceName){//创建一个AsyncTask去这行请求为什么newMyTast<T>(context,message,isShowDialog,callBack,beanClass,serviceName).execute("");}/***发送请求数据**@paramrequestStr*请求数据*@throwsException*异常*/publicvoidsend(StringrequestStr)throwsException{if(outputStream==null){outputStream=socket.getOutputStream();}//编码byte[]encryptBytes=AESUtil.encrypt(requestStr.getBytes());//压缩byte[]compressBytes=GZipUtils.compress(encryptBytes);//写入数据流操作DataOutputStreamdos=newDataOutputStream(outputStream);dos.writeInt(compressBytes.length);dos.write(compressBytes);}/***接收数据**@return服务器返回的字符数据*@throwsException*/publicStringreceive()throwsException{if(inputStream==null){inputStream=socket.getInputStream();}//获取输入流读取服务端传递过来的流DataInputStreamdin=newDataInputStream(inputStream);intavailableLen=din.readInt();//阻塞方法byte[]data=receiveBytes(din,availableLen);//读取字节数据byte[]uncompress=GZipUtils.decompress(data);byte[]decrypt=AESUtil.decrypt(uncompress);returnnewString(decrypt,"UTF-8");}/***得到接收的byte数组数据**@paramis*输入流(服务端传递过来的数据)*@paramlength*读取的长度*@return字节数组*@throwsIOException*/privatebyte[]receiveBytes(InputStreamis,intlength)throwsIOException{inttmpLength=1024;//每次读取最大缓冲区大小byte[]ret=newbyte[length];intreaded=0,offset=0,left=length;byte[]bs=newbyte[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;//读取的长度减小}}returnret;}/***关闭流**@throwsIOException*/publicvoiddisconnect()throwsIOException{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网络请求(参数,进度,结果)*/classMyTast<T>extendsAsyncTask<String,Integer,NetResponse>{privateContextcontext;privateStringmessage;privatebooleanisShowDialog;privateTcpRequsetCallBackcallBack;privateTbeanClass;privateStringserviceName;publicMyTast(finalContextcontext,finalStringmessage,booleanisShowDialog,TcpRequsetCallBackcallBack,TbeanClass,StringserviceName){this.context=context;this.message=message;this.isShowDialog=isShowDialog;this.callBack=callBack;this.beanClass=beanClass;this.serviceName=serviceName;}/***请求数据前*/protectedvoidonPreExecute(){if(!ConnectUtils.isNetworkConnected(context)){Toast.makeText(context,"网络未连接,请检查网络",0).show();return;}if(isShowDialog){//判断是否需要显示dialogpd=newProgressDialog(context);if(this.message==null){//判断要显示的文字pd.setMessage("正在加载数据");}else{pd.setMessage(message);}pd.show();}}/***请求数据中*/protectedNetResponsedoInBackground(String...params){NetResponsenrp=newNetResponse();try{socket=newSocket("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);}}returnnrp;}/***请求数据结束后*/protectedvoidonPostExecute(NetResponseresult){if(ResponseStatus.OK==result.status){//请求成功callBack.onRequestSuccess(result.responseMsg);}else{//请求失败callBack.onErr(result);}}}}
TcpRequsetCallBack
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970/***@authorqiwenming*@time2015年5月30日下午11:35:41*@说明Tcp请求的回调类*/publicabstractclassTcpRequsetCallBack<TR>{// privateBaseRspBean<TR>baseRsp;privateClass<TR>beanClass;privateStringTAG=TcpRequsetCallBack.class.getName();/***构造函数*@param<TR>*@parambeanClass*/publicTcpRequsetCallBack(Class<TR>beanClass){this.beanClass=beanClass;}/***请求成功的方法*@paramresponseMsg*/public<T>voidonRequestSuccess(StringresponseMsg){Gsongson=newGson();try{TRbean=gson.fromJson(responseMsg,beanClass);if(beaninstanceofBaseRespBean){BaseRespBeanbnBean=(BaseRespBean)bean;if(!"0000".equals(bnBean.result_code)){//这里的判断根据规定的响应码来判断onfail(bnBean.result_code,bnBean.result_msg);return;}onSuccess(bean);}}catch(JsonSyntaxExceptione){NetResponsenetRspJson=newNetResponse();netRspJson.exception=e;netRspJson.responseMsg=TAG+":onRequestSuccess():JsonSyntaxException:响应数据转换json的时候处理问题";onErr(netRspJson);}};/***得到正确的数据*@paramheader*@paramresultMsg*@paramresultCode*/publicabstractvoidonSuccess(TRbean);/***数据错误*@paramfailDesc错误信息*@paramresult_code错误码*/publicvoidonfail(Stringresult_code,StringfailDesc){Log.e(TAG+".onfail","请求数据失败:result_code:"+result_code+"failDesc:"+failDesc);};/***请求报错*@paramnetQuest*/publicvoidonErr(NetResponsenetRsp){Log.e(TAG+".onErr",netRsp.responseMsg);netRsp.exception.printStackTrace();};}
BaseRespBean
123456789/***@authorqiwenming*@time2015年5月31日上午12:11:18*@说明响应基类*/publicclassBaseRespBeanimplementsSerializable{publicStringresult_code;publicStringresult_msg;}
1.LoginReqBean
2.BaseRespBean
123456789/***@authorqiwenming*@time2015年5月30日下午11:57:40*@说明登陸請求的javabean*/publicclassLoginReqBeanimplementsSerializable{publicStringusername;publicStringpassword;}
123456789/***@authorqiwenming*@time2015年5月31日上午12:11:18*@说明响应基类*/publicclassBaseRespBeanimplementsSerializable{publicStringresult_code;publicStringresult_msg;}
3.LoginRespBean
12345678910111213/***@authorqiwenming*@time2015年5月31日上午12:10:41*@说明登陆响应类*/publicclassLoginRespBeanextendsBaseRespBean{publicLoginDatadata;publicclassLoginDataimplementsSerializable{publicStringnickName;publicintage;}}
三、登陆中客户端登陆方法
1234567891011121314151617181920212223242526272829303132333435363738/***登陆**@paramv*/publicvoidtoLogin(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=newLoginReqBean();bean.username=name;bean.password=pwd;newTcpUtil().requestData(this,"登陆请求中...",true,newTcpRequsetCallBack<LoginRespBean>(LoginRespBean.class){@OverridepublicvoidonSuccess(LoginRespBeanbean){//登陆成功Intenti=newIntent(MainActivity.this,HomeActivity.class);i.putExtra("loginbean",bean);startActivity(i);MainActivity.this.finish();}@Overridepublicvoidonfail(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*/publicclassAesDemo{publicstaticvoidmain(String[]args){test();}publicstaticvoidtest(){ServerSocketss=null;try{ss=newServerSocket(8888);while(true){finalSockets=ss.accept();newThread(newRunnable(){publicvoidrun(){try{DataInputStreamdis=newDataInputStream(s.getInputStream());//读取数据byte[]recData=(newTcpUtil()).readData(dis);System.out.println("长度:"+recData.length);////解压缩byte[]uncompress=GZipUtils.decompress(recData);//解密byte[]decrypt=AESUtil.decrypt(uncompress);//======================响应部分================================DataOutputStreamdos=newDataOutputStream(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*/publicstatic<T>StringgetSendData(TbeanClass){if(beanClass==null){return"";}Tbean=beanClass;Gsongson=newGson();Stringstr=gson.toJson(bean);returnstr;}/***处理数据*/publicstaticbyte[]handlerData(byte[]decrypt){StringreqMsg=newString(decrypt);System.out.println("请求的数据:"+reqMsg);Gsongson=newGson();//获得数据LoginReqBeanbean=gson.fromJson(reqMsg,LoginReqBean.class);LoginRespBeanrespBean=newLoginRespBean();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);returnrespMsg.getBytes();}}
本文详细介绍了TCP网络通信的实现方式,包括实体类转为JSON、请求字符串拼接、网络请求回调类、登录请求的JavaBean及响应类,并通过Java控制台程序模拟了后台的主要方法。此外,还展示了移动端登录请求的具体实现过程。
6367

被折叠的 条评论
为什么被折叠?



