目标

Demo是通过Java ServerSocketSocket 通信实现客户端发送消息发送文件到服务器,服务器接收到消息和文件,并且实现解决inputStream.read()的阻塞问题思路。

服务器端

创建ServerSocket服务器

serverSocket = new ServerSocket(port);//首先创建一个服务端口
//等待客户端的连接请求
socket = serverSocket.accept();

等待Socket客户端连接

                //等待客户端的连接请求socket = serverSocket.accept();final String socketAddress = socket.getRemoteSocketAddress().toString();runOnUiThread(new Runnable() {@Overridepublic void run() {Toast.makeText(ServerActivity.this, "成功建立与客户端的连接 : " + socketAddress, Toast.LENGTH_SHORT).show();Log.i("Lin", "成功建立与客户端的连接 : " + socketAddress);}});

接收Socket客户端信息

为了防止接收消息时,服务器inputStream.read()读取消息时产生阻塞,以换行符**("\n")结束inputStream.read()**

                            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() {@Overridepublic 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() {@Overridepublic void run() {mProgressDialog.setMessage((finalFileSize * 100 / fileLength) + "%");mProgressDialog.show();}});if (md5.equals(fileMD5)) {fileOutputStream.close();runOnUiThread(new Runnable() {@Overridepublic 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() {@Overridepublic 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());)

向ServerSocket服务器发送文件

File file = new File(finalImagePath);if (file.exists()) {final String fileMD5 = nullOfString(getFileMD5(file));OutputStream outputStream = socket.getOutputStream();runOnUiThread(new Runnable() {@Overridepublic 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()**阻塞。

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

Android Java 必备:Socket通信相关推荐

  1. 基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互

    基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互 一.前言 1.Java服务端程序代码的项目名为TcpSocketServerOfJava,包名为com.exam ...

  2. Java中Socket通信-客户端与服务端相互传输对象数据

    场景 Java中Socket通信-服务端和客户端双向传输字符串实现: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1084885 ...

  3. Java中Socket通信-客户端向服务端发送照片

    场景 Java中Socket通信-服务端和客户端双向传输字符串实现: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1084885 ...

  4. delphi和 java通过socket通信的中文问题

    delphi和 java通过socket通信的中文问题 在delphi中把字符串转换下 Msg:=Utf8Encode(Msg); java中接收 java中用了mina public static ...

  5. 树莓派与Android客户端进行socket通信

    转自:https://blog.csdn.net/lj779323436/article/details/79911322 我在此基础上时间并进行了些许修正. 先在树莓派上创建热点: https:// ...

  6. Android简单实现Socket通信,客户端连接服务器后,服务器向客户端发送文字数据

    案例实现的是简单的Socket通信,当客户端(Android客户端)连接到指定服务器以后,服务器向客户端发送一句话文字信息(你可以拓展其它的了) 先看一下服务端程序的实现吧 Server.java i ...

  7. Android进程间通信之socket通信

    用Java中的socket编程. 通过socket实现两个应用之间的通信,可以接收和发送数据,同时将接收到的数据显示在activity界面上. Server端: ServerLastly.java p ...

  8. 使用JAVA实现Socket通信,TCP、UDP简析。

    Socket通信是一种非常重要的通信方式,它使用起来简单方便,也很容易学会,下面就我所知道的简单记录一下. 首先是UDP的方式.(通过Android与PC端进行通信) 发送端: package com ...

  9. Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)

    JAVA Socket简介 所谓socket 通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答 ...

最新文章

  1. 23种设计模式(上)
  2. 搭建基础架构-Order
  3. ACM学习历程—HihoCoder1309任务分配(排序 贪心)
  4. Windows系统下,使用Emacs+Putty操作远程机器
  5. 西瓜书+实战+吴恩达机器学习(二三)EM算法和变分推断
  6. UVA 2519 Radar Installtion
  7. C#项目”XXXXX”针对的是”.NETFramework,Version=v4.7.1”但此计算机没有安装它
  8. cad自动标注界址点_CAD自带“块属性”即可实现自动标注坐标
  9. C++控制台模拟网上购物商城
  10. 批量导出二维码并生成压缩文件
  11. 中国工科研究生200多篇英文论文中最常见的习惯(The Most Common Habits from more than 200 English Papers written by Gradua)
  12. 出入库管理系统-精致版
  13. payscale 美国计算机专业,2016PayScale美国大学排名:计算机专业
  14. 查找Mac序列号的9种方法
  15. 什么是迭代器(Iterator)
  16. 链表实现电话簿(C++)
  17. SpringBoot核心注解
  18. 【学习笔记】群论入门
  19. 新手程序员如何提升自己的编程能力
  20. 中国计算机软件工程大学专业,全国开设软件工程专业院校有哪些 都有什么大学名单...

热门文章

  1. poco库学习笔记(1) poco库的安装
  2. 【论文速递】BANDWIDTH EXTENSION IS ALL YOU NEED
  3. 对策《四川省本科毕业论文(设计)抽检实施细则》(四)准备答辩
  4. 部署“极客猿导航geek-navigation遇到的问题”——作者没说但你就会遇到(1)
  5. Windows系列原版系统镜像下载
  6. WEBGUI配置和如何启动WEBGUI
  7. IBM-IPD研发管理职能
  8. 体积最小,极速秒装的APK安装器
  9. Elasticsearch Date类型,时间存储相关说明
  10. iOS和Android使用同一个二维码自动跳转不同下载页面链接(附生成二维码地址方法)