Android Java 必备:Socket通信
目标
Demo是通过Java ServerSocket 和 Socket 通信实现客户端发送消息和发送文件到服务器,服务器接收到消息和文件,并且实现解决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通信相关推荐
- 基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互
基于TCP/IP协议的Java服务端与Android客户端的Socket通信及数据交互 一.前言 1.Java服务端程序代码的项目名为TcpSocketServerOfJava,包名为com.exam ...
- Java中Socket通信-客户端与服务端相互传输对象数据
场景 Java中Socket通信-服务端和客户端双向传输字符串实现: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1084885 ...
- Java中Socket通信-客户端向服务端发送照片
场景 Java中Socket通信-服务端和客户端双向传输字符串实现: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1084885 ...
- delphi和 java通过socket通信的中文问题
delphi和 java通过socket通信的中文问题 在delphi中把字符串转换下 Msg:=Utf8Encode(Msg); java中接收 java中用了mina public static ...
- 树莓派与Android客户端进行socket通信
转自:https://blog.csdn.net/lj779323436/article/details/79911322 我在此基础上时间并进行了些许修正. 先在树莓派上创建热点: https:// ...
- Android简单实现Socket通信,客户端连接服务器后,服务器向客户端发送文字数据
案例实现的是简单的Socket通信,当客户端(Android客户端)连接到指定服务器以后,服务器向客户端发送一句话文字信息(你可以拓展其它的了) 先看一下服务端程序的实现吧 Server.java i ...
- Android进程间通信之socket通信
用Java中的socket编程. 通过socket实现两个应用之间的通信,可以接收和发送数据,同时将接收到的数据显示在activity界面上. Server端: ServerLastly.java p ...
- 使用JAVA实现Socket通信,TCP、UDP简析。
Socket通信是一种非常重要的通信方式,它使用起来简单方便,也很容易学会,下面就我所知道的简单记录一下. 首先是UDP的方式.(通过Android与PC端进行通信) 发送端: package com ...
- Java的Socket通信----通过 Socket 实现 TCP 编程之多线程demo(2)
JAVA Socket简介 所谓socket 通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答 ...
最新文章
- 23种设计模式(上)
- 搭建基础架构-Order
- ACM学习历程—HihoCoder1309任务分配(排序 贪心)
- Windows系统下,使用Emacs+Putty操作远程机器
- 西瓜书+实战+吴恩达机器学习(二三)EM算法和变分推断
- UVA 2519 Radar Installtion
- C#项目”XXXXX”针对的是”.NETFramework,Version=v4.7.1”但此计算机没有安装它
- cad自动标注界址点_CAD自带“块属性”即可实现自动标注坐标
- C++控制台模拟网上购物商城
- 批量导出二维码并生成压缩文件
- 中国工科研究生200多篇英文论文中最常见的习惯(The Most Common Habits from more than 200 English Papers written by Gradua)
- 出入库管理系统-精致版
- payscale 美国计算机专业,2016PayScale美国大学排名:计算机专业
- 查找Mac序列号的9种方法
- 什么是迭代器(Iterator)
- 链表实现电话簿(C++)
- SpringBoot核心注解
- 【学习笔记】群论入门
- 新手程序员如何提升自己的编程能力
- 中国计算机软件工程大学专业,全国开设软件工程专业院校有哪些 都有什么大学名单...
热门文章
- poco库学习笔记(1) poco库的安装
- 【论文速递】BANDWIDTH EXTENSION IS ALL YOU NEED
- 对策《四川省本科毕业论文(设计)抽检实施细则》(四)准备答辩
- 部署“极客猿导航geek-navigation遇到的问题”——作者没说但你就会遇到(1)
- Windows系列原版系统镜像下载
- WEBGUI配置和如何启动WEBGUI
- IBM-IPD研发管理职能
- 体积最小,极速秒装的APK安装器
- Elasticsearch Date类型,时间存储相关说明
- iOS和Android使用同一个二维码自动跳转不同下载页面链接(附生成二维码地址方法)