Android Socket通訊

目標

Demo是經過Java ServerSocketSocket 通訊實現客戶端發送消息發送文件到服務器,服務器接收到消息和文件,而且實現解決inputStream.read()阻塞問題思路。git

服務器端

建立ServerSocket服務器

serverSocket = new ServerSocket(port);//首先建立一個服務端口
//等待客戶端的鏈接請求
socket = serverSocket.accept();

等待Socket客戶端鏈接

//等待客戶端的鏈接請求
                socket = serverSocket.accept();
                final String socketAddress = socket.getRemoteSocketAddress().toString();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(ServerActivity.this, "成功創建與客戶端的鏈接 : " + socketAddress, Toast.LENGTH_SHORT).show();
                        Log.i("Lin", "成功創建與客戶端的鏈接 : " + socketAddress);
                    }
                });

接收Socket客戶端信息

爲了防止接收消息時,服務器inputStream.read()讀取消息時產生阻塞,以換行符("\n")結束inputStream.read()github

byte[] bytes = new byte[1];
                            StringBuilder info = new StringBuilder();
                            while (inputStream.read(bytes) != -1) {
                                String str = new String(bytes);
                                if (str.equals("\n")) {
                                    break;
                                }
                                info.append(new String(bytes));
                            }
                            final String finalInfo = info.toString();
                            Log.i("Lin", "text = " + finalInfo);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mEtReceive.setText(mEtReceive.getText().toString() + socketAddress + " : " + finalInfo + "\n");
                                }
                            });

接收Socket客戶端文件

爲了防止接收消息時,服務器inputStream.read()接受文件時產生阻塞,以文件MD5校驗碼進行校驗,從而結束inputStream.read()服務器

byte[] remote = new byte[32];
                            String md5 = "";
                            if (inputStream.read(remote) != -1) {
                                md5 = nullOfString(new String(remote));
                            }

                            final String root = Environment.getExternalStorageDirectory().getPath();
                            Log.i("Lin", root);
                            byte[] inputByte = new byte[1024 * 1024];
                            int len = 0;
                            long fileSize = 0;

                            DataInputStream dis = new DataInputStream(inputStream);
                            // 文件名和長度
                            String fileName = dis.readUTF();
                            final long fileLength = dis.readLong();
                            Log.i("Lin", "fileName = " + fileName);
                            Log.i("Lin", "fileLength = " + fileLength);
                            mPath = root + "/ECG/" + fileName;
                            File file = new File(root + "/ECG/");
                            if (!file.exists()) file.mkdir();
                            file = new File(mPath);
                            FileOutputStream fileOutputStream = new FileOutputStream(file);
                            String fileMD5 = nullOfString(getFileMD5(new File(mPath)));
                            while (!md5.equals(fileMD5) && (len = dis.read(inputByte, 0, inputByte.length)) > 0) {
                                fileSize += len;
                                fileOutputStream.write(inputByte, 0, len);
                                fileOutputStream.flush();
                                fileMD5 = nullOfString(getFileMD5(new File(mPath)));
                                Log.i("Lin", "md5 = " + md5 + " file = " + fileMD5);
                                Log.i("Lin", "fileLength = " + fileLength + " fileSize = " + fileSize + " " + (fileSize * 100 / fileLength) + "%")
                                ;
                                final long finalFileSize = fileSize;
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        mProgressDialog.setMessage((finalFileSize * 100 / fileLength) + "%");
                                        mProgressDialog.show();
                                    }
                                });
                                if (md5.equals(fileMD5)) {
                                    fileOutputStream.close();
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            mProgressDialog.hide();
                                        }
                                    });
                                }
                            }
                            Log.i("Lin", "md52 = " + md5 + " file2 = " + getFileMD5(file));
                            fileMD5 = nullOfString(getFileMD5(new File(mPath)));
                            Log.i("Lin", "file = " + fileMD5);
                            final String finalFileMD = fileMD5;
                            final String finalMd = md5;
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    mEtReceive.setText(mEtReceive.getText().toString() + "文件路徑:" + mPath + "\n");
                                    mEtReceive.setText(mEtReceive.getText().toString() + "file = " + finalFileMD + "\n");
                                    mEtReceive.setText(mEtReceive.getText().toString() + "text = " + finalMd + "\n");
                                }
                            });

客戶端

建立Socket客戶端

鏈接ServerSocket服務器

socket = new Socket();
socket.connect(new InetSocketAddress(ip, port));
//ip= 服務器ip
//port= 服務器端口

向ServerSocket服務器發送消息

try {
                            if (socket == null) return;
                            OutputStream om = socket.getOutputStream();
                            om.write(Constant.SERVER_TEXT.getBytes());
                            om.write(returnServer.getBytes());
                            om.write("\n".getBytes());//[10]
                            om.flush();
                        } catch (Exception e) {
                            e.printStackTrace();
                            Log.i("Lin", e.toString());
                        }

爲了防止發送消息時,服務器inputStream.read()讀取消息時產生阻塞,客戶端以換行符結束髮送(om.write("\n".getBytes());)app

向ServerSocket服務器發送文件

File file = new File(finalImagePath);
                                    if (file.exists()) {
                                        final String fileMD5 = nullOfString(getFileMD5(file));
                                        OutputStream outputStream = socket.getOutputStream();
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                mEtReceive.setText(mEtReceive.getText().toString() + "file = " + fileMD5 + "\n");
                                            }
                                        });

                                        FileInputStream fileInputStream = new FileInputStream(file);
                                        outputStream.write(Constant.SERVER_FILE.getBytes());
                                        outputStream.flush();
                                        outputStream.write(fileMD5.getBytes());
                                        outputStream.flush();
                                        DataOutputStream dis = new DataOutputStream(outputStream);
                                        // 文件名和長度
                                        dis.writeUTF(file.getName());
                                        dis.flush();
                                        dis.writeLong(file.length());
                                        dis.flush();
                                        byte[] buffer = new byte[1024 * 1024];
                                        int len = 0;
                                        while ((len = fileInputStream.read(buffer, 0, buffer.length)) > 0) {
                                            dis.write(buffer, 0, len);
                                            dis.flush();
                                        }
                                        fileInputStream.close();
                                        Log.i("Lin", "傳輸成功");
                                    }

爲了防止發送文件時,服務器inputStream.read()接受文件時產生阻塞,客戶端先向服務器發送文件MD5校驗碼再發送文件,服務器對接收文件進行校驗從而結束inputStream.read()阻塞。socket

Demo中發送格式

字符:SERVER_TEXT + 字符 + 換行符(\n)

文件:SERVER_FILE + 文件MD5校驗碼 + 文件

獲取文件MD5

private static String getFileMD5(File file) {
        if (!file.isFile()) {
            return null;
        }
        MessageDigest digest;
        FileInputStream in;
        try {
            byte[] buffer = new byte[1024];
            int len;
            digest = MessageDigest.getInstance("MD5");
            in = new FileInputStream(file);
            while ((len = in.read(buffer, 0, 1024)) != -1) {
                digest.update(buffer, 0, len);
            }
            in.close();
            BigInteger bigInt = new BigInteger(1, digest.digest());
            return bigInt.toString(16);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

GitHub

THE END

相關文章
相關標籤/搜索