android基于socket的局域网内服务器与客户端加密通信(2)

时间:2017-04-14 08:09:48 

(3)客户端主界面 Function_Socket_Client.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 import android.app.ProgressDialog; import android.util.Log; import android.view.View; import android.widget.EditText; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import butterknife.BindView; import butterknife.OnClick; /** * 客户端界面 */ public classFunction_Socket_Client extendsBaseEventActivity { @BindView(R.id.edtTxt_Content) EditText edtTxt_Content; @BindView(R.id.edtTxt_serverAddress) EditText edtTxt_serverAddress; privateProgressDialog mProgressDialog;//加载的小菊花 /** * 初始化 */ @Override protectedvoid init() { } @Override protectedint getLayoutResId() { returnR.layout.function_socket_client; } @OnClick(R.id.btn_encryptAndSend) publicvoidonClick(View v) { switch(v.getId()) { caseR.id.btn_encryptAndSend: String s = edtTxt_Content.getText().toString().trim(); String ip = edtTxt_serverAddress.getText().toString().trim(); if(ToolUtil.IsIpv4(ip)) { newSendDataThread(ip, AESUtil.encrypt(ConstantUtil.password, s), ConstantUtil.port).start();//消息发送方启动线程发送消息 showProgressDialog("尝试发送数据到 "+ ip, true); } else{ ToastUtil.showToast(this, "IP不合法!"); } break; } } /** * 连接结果 * * @param resultCode 0:连接超时;1:发送成功 2:失败 */ @Subscribe(threadMode = ThreadMode.MAIN) publicvoidsendResult(Integer resultCode) { Log.i("succ", "="+ resultCode); dismissProgressDialog(); switch(resultCode) { caseConstantUtil.CODE_SUCCESS: ToastUtil.showToast(this, "发送成功"); break; caseConstantUtil.CODE_TIMEOUT: ToastUtil.showToast(this, "连接超时"); break; caseConstantUtil.CODE_UNKNOWN_HOST: ToastUtil.showToast(this, "错误-未知的host"); break; } } /** * 数据加载小菊花 * * @param msg 内容 * @param isCancel 是否允许关闭 true - 允许 false - 不允许 */ publicvoidshowProgressDialog(finalString msg, finalbooleanisCancel) { runOnUiThread(new Runnable() { @Override publicvoidrun() { try{ if(mProgressDialog == null) { mProgressDialog = newProgressDialog(Function_Socket_Client.this); } if(mProgressDialog.isShowing()) { return; } mProgressDialog.setMessage(msg); mProgressDialog.setCancelable(isCancel); mProgressDialog.setCanceledOnTouchOutside(false); mProgressDialog.setOnCancelListener(null); mProgressDialog.show(); } catch(Exception e) { e.printStackTrace(); } } }); } /** * 隐藏数据加载的进度小菊花 **/ publicvoiddismissProgressDialog() { try{ if(mProgressDialog != null&& mProgressDialog.isShowing()) { runOnUiThread( newRunnable() { @Override publicvoidrun() { mProgressDialog.dismiss(); } } ); } } catch(Exception e) { e.printStackTrace(); } } }

(4)LocalService.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * 此服务用于启动监听线程 */ public classLocalService extendsService { privateIBinder iBinder = newLocalService.LocalBinder(); @Override publicIBinder onBind(Intent intent) { returniBinder; } @Override publicintonStartCommand(Intent intent, intflags, intstartId) { returnSTART_STICKY; } publicvoidstartWaitDataThread() { newListenThread(ConstantUtil.port).start(); } //定义内容类继承Binder publicclassLocalBinder extends Binder { //返回本地服务 publicLocalService getService() { returnLocalService.this; } } }

(5)ListenThread.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import org.greenrobot.eventbus.EventBus; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; /** * 监听线程 */ public classListenThread extendsThread { privateServerSocket serverSocket; publicListenThread(int port) { try{ serverSocket = newServerSocket(port); } catch(IOException e) { e.printStackTrace(); } } @Override publicvoidrun() { while(true) { try{ if(serverSocket != null) { Socket socket = serverSocket.accept(); InputStream inputStream = socket.getInputStream(); if(inputStream != null) { BufferedReader in = newBufferedReader(new InputStreamReader(inputStream, "UTF-8")); String str; str = in.readLine(); EventBus.getDefault().post(str); socket.close(); } } } catch(IOException e) { e.printStackTrace(); } } } }

(6)SendDataThread.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 import android.util.Log; import org.greenrobot.eventbus.EventBus; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.net.UnknownHostException; /** * 数据发送线程 */ public classSendDataThread extendsThread { privateSocket socket; privateString ip;//接收方的IP privateintport;//接收方的端口号 privateString data;//准备发送的数据 publicSendDataThread(String ip, String data, intport) { this.ip = ip; this.data = data; this.port = port; } @Override publicvoidrun() { try{ socket = newSocket(); socket.connect(new InetSocketAddress(ip,port),ConstantUtil.TIME_MILLIS);//设置超时时间 } catch(UnknownHostException e) { EventBus.getDefault().post(ConstantUtil.CODE_UNKNOWN_HOST); Log.d("error", "SendDataThread.init() has UnknownHostException" + e.getMessage()); } catch(SocketTimeoutException e) { EventBus.getDefault().post(ConstantUtil.CODE_TIMEOUT); Log.d("error", "SendDataThread.init() has TimeoutException:"+ e.getMessage()); }catch(IOException e){ Log.d("error", "SendDataThread.init() has IOException:"+ e.getMessage()); } if(socket != null&&socket.isConnected()) { try{ OutputStream ops = socket.getOutputStream(); OutputStreamWriter opsw = newOutputStreamWriter(ops); BufferedWriter writer = newBufferedWriter(opsw); writer.write(data + " ");//由于socket使用缓冲区进行读写数据,因此使用 用于表明数据已写完.不加这个会导致数据无法发送 EventBus.getDefault().post(ConstantUtil.CODE_SUCCESS); writer.flush(); } catch(IOException e) { e.printStackTrace(); } } } }

(7)AESUtil.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 import android.util.Log; import java.io.UnsupportedEncodingException; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; /** * AES加密工具类 */ public classAESUtil { // private static final String CipherMode = "AES/ECB/PKCS5Padding";使用ECB加密,不需要设置IV,但是不安全 privatestatic finalString CipherMode = "AES/CFB/NoPadding";//使用CFB加密,需要设置IV /** * 生成加密后的密钥 * * @param password 密钥种子 * @return isSucceed */ privatestatic SecretKeySpec createKey(String password) { byte[] data = null; if(password == null) { password = ""; } StringBuilder sb = newStringBuilder(32); sb.append(password); while(sb.length() < 32) { sb.append("0"); } if(sb.length() > 32) { sb.setLength(32); } try{ data = sb.toString().getBytes("UTF-8"); } catch(UnsupportedEncodingException e) { e.printStackTrace(); } returnnewSecretKeySpec(data, "AES"); } // /** 加密字节数据 **/ privatestatic byte[] encrypt(byte[] content, String password) { try{ SecretKeySpec key = createKey(password); System.out.println(key); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.ENCRYPT_MODE, key, newIvParameterSpec( newbyte[cipher.getBlockSize()])); returncipher.doFinal(content); } catch(Exception e) { e.printStackTrace(); } returnnull; } // /** 加密(结果为16进制字符串) **/ publicstatic String encrypt(String password, String content) { Log.d("加密前", "seed="+ password + " content="+ content); byte[] data = null; try{ data = content.getBytes("UTF-8"); } catch(Exception e) { e.printStackTrace(); } data = encrypt(data, password); String result = byte2hex(data); Log.d("加密后", "result="+ result); returnresult; } // /** 解密字节数组 **/ privatestatic byte[] decrypt(byte[] content, String password) { try{ SecretKeySpec key = createKey(password); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.DECRYPT_MODE, key, newIvParameterSpec( newbyte[cipher.getBlockSize()])); returncipher.doFinal(content); } catch(Exception e) { e.printStackTrace(); } returnnull; } // /** 解密16进制的字符串为字符串 **/ publicstatic String decrypt(String password, String content) { Log.d("解密前", "seed="+ password + " content="+ content); byte[] data = null; try{ data = hex2byte(content); } catch(Exception e) { e.printStackTrace(); } data = decrypt(data, password); if(data == null) returnnull; String result = null; try{ result = newString(data, "UTF-8"); Log.d("解密后", "result="+ result); } catch(UnsupportedEncodingException e) { e.printStackTrace(); } returnresult; } // /** 字节数组转成16进制字符串 **/ privatestaticString byte2hex(byte[] b) { // 一个字节的数, StringBuilder sb = newStringBuilder(b.length * 2); String tmp ; for(byteaB : b) { // 整数转成十六进制表示 tmp = (Integer.toHexString(aB & 0XFF)); if(tmp.length() == 1) { sb.append("0"); } sb.append(tmp); } returnsb.toString().toUpperCase(); // 转成大写 } // /** 将hex字符串转换成字节数组 **/ privatestaticbyte[] hex2byte(String inputString) { if(inputString == null || inputString.length() < 2) { returnnewbyte[0]; } inputString = inputString.toLowerCase(); intl = inputString.length() / 2; byte[] result = new byte[l]; for(inti = 0; i < l; ++i) { String tmp = inputString.substring(2* i, 2* i + 2); result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF); } returnresult; } }

(8)ConstantUti.java

?

1 2 3 4 5 6 7 8 9 10 11 /** * 常量类 */ public classConstantUtil { publicstatic finalint TIME_MILLIS = 5 * 1000;//连接超时时间 publicstatic finalint port = 25256;//端口号 publicstatic finalString password = "123456885";//加密所使用的密钥 publicstatic finalint CODE_TIMEOUT = 0;//连接超时 publicstatic finalint CODE_SUCCESS = 1;//连接成功 publicstatic finalint CODE_UNKNOWN_HOST = 2;//错误-未知的host }

(9)ToolUtil.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 import android.util.Log; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; /** * 工具类 */ public classToolUtil { /** * 获取ip地址 * 如果是移动网络,会显示自己的公网IP,如果是局域网,会显示局域网IP * 因此本例中服务器端需要断开移动网络以得到本机局域网IP */ publicstatic String getHostIP() { String hostIp = null; try{ Enumeration nis = NetworkInterface.getNetworkInterfaces(); InetAddress ia; while(nis.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) nis.nextElement(); Enumeration<InetAddress> ias = ni.getInetAddresses(); while(ias.hasMoreElements()) { ia = ias.nextElement(); if(ia instanceofInet6Address) { continue;// skip ipv6 } String ip = ia.getHostAddress(); if(!"127.0.0.1".equals(ip)) { hostIp = ia.getHostAddress(); break; } } } } catch(SocketException e) { Log.i("error", "SocketException"); e.printStackTrace(); } returnhostIp; } /** * 判断地址是否为IPV4地址 */ publicstatic booleanIsIpv4(String ipv4) { if(ipv4 == null|| ipv4.length() == 0) { returnfalse;//字符串为空或者空串 } String[] parts = ipv4.split("\.");//因为java doc里已经说明, split的参数是reg, 即正则表达式, 如果用"|"分割, 则需使用"\|" if(parts.length != 4) { returnfalse;//分割开的数组根本就不是4个数字 } for(String part : parts) { try{ intn = Integer.parseInt(part); if(n < 0|| n > 255) { returnfalse;//数字不在正确范围内 } } catch(NumberFormatException e) { returnfalse;//转换数字不正确 } } returntrue; } }

(10)ToastUtil.java

?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import android.content.Context; import android.widget.Toast; public classToastUtil { privatestatic Toast mToast = null; /** * Toast方法 * * @param text 需要展示的文本 * @param context 所需上下文 */ publicstatic voidshowToast(Context context, String text) { if(text != null) { if(mToast == null) { mToast = Toast.makeText(context, text, Toast.LENGTH_SHORT); } else{ mToast.setText(text); mToast.setDuration(Toast.LENGTH_SHORT); } mToast.show(); } } }

3.权限及声明

?

1 2 3 4 5 <uses-permissionandroid:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <!--service部分--> <serviceandroid:name="com.test.test.LocalService"/>

看不过瘾?点击下面链接!
本站微信公众号:gsjx365,天天有好故事感动你!

上一页12下一页

相关电脑知识

美图欣赏

电脑知识排行榜