Android使用Socket(Tcp/Udp)协议进行数据传输(传输大文件)
2016-08-31 13:38
1216 查看
Socket是什么:所谓Socket 通常也称作”套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。Socket内部又有两种协议(Tcp/Udp),我们来说说其各自的特点。
先来说说网络编程的三要素
1.IP地址:网络中计算机的唯一标识 2.端口 3.协议:通信的规则
Tcp/Udp特点
一、 TCP(协议):建立连接,形成传输数据的通道
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率稍微低点
二. UDP(协议):
将数据及源和目的封装在数据包中,不需要建立连接
每个数据包的大小限制在64K内
因无连接,是不可靠协议
不需要建立连接,速度快
Socket工作图解
TCP协议进行数据传输,实现两台设备的一个简单数据发送。
客户端发送数据
/** * @param serverAddress 要发送到服务端的ip * 1.创建socket并指定ip和端口号 * 2.获取输出流,写数据 * 3.释放资源 * 4.Tcp一定要先开接收端 */ public void send_tcp(String serverAddress) { try { Socket s = new Socket(serverAddress, WIFIAdmin.PORT); //为了发送数据,应该获得socket流中的输出流 OutputStream out = s.getOutputStream(); out.write((content.getText().toString()).getBytes()); s.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
服务端接收数据
/** * TCP协议接收数据 * 1.创建接收端的Socket对象 * 2.监听客户端接收,返回一个Socket对象 * 3.获取输入流,读取数据显示在控制台 * 4.释放资源 */ public void receive_tcp() { try { //1.建立连接,监听端口 ServerSocket ss = new ServerSocket(WIFIAdmin.PORT); //2.连接客户端对象 while (true) { //阻塞式方法,只有客户端连接了才会继续往下运行 Socket accept = ss.accept(); //获取ip String ip = accept.getInetAddress().getHostAddress(); //3.获取客户端发送过来的数据 InputStream in = accept.getInputStream(); //4.开始读取,获取输入信息 BufferedReader bff = new BufferedReader(new InputStreamReader(in)); //读取信息 String line; final StringBuilder sb = new StringBuilder(); while ((line = bff.readLine()) != null) { sb.append(line); } Message message = new Message(); message.obj = sb.toString(); handler.sendMessage(message); //5.关闭 //ss.close(); } } catch (IOException e) { e.printStackTrace(); } }
现在来看下UDP协议是怎么进行数据传输的。
先来看下发送端
/* * UDP协议发送数据: * 1.创建发送端Socket对象 * 2.创建数据,并把数据打包 * 3.调用Socket对象发送方法发送数据包 * 4.释放资源 */ private void udpSendMessage() { DhcpInfo info = wifiManager.getDhcpInfo(); String serverAddress = WIFIAdmin.intToIp(info.serverAddress); // 创建发送端Socket对象 try { // 创建发送端Socket对象 DatagramSocket ds = new DatagramSocket(); // 创建数据,并把数据打包 byte[] bys = content.getText().toString().getBytes(); DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName(serverAddress), WIFIAdmin.UDP_PORT); // 调用Socket对象发送方法发送数据包 ds.send(dp); // 释放资源 ds.close(); } catch (Exception e) { e.printStackTrace(); } }
在瞄一下接收端
/* * UDP协议接收数据: * 1.创建接收端Socket对象 * 2.创建一个数据包(接收容器) * 3.调用Socket对象接收方法接收数据包 * 4.解析数据包 * 5.释放资源 */ private void receive_udp() { try { // 创建接收端Socket对象 DatagramSocket ds = new DatagramSocket(WIFIAdmin.UDP_PORT); // 创建一个数据包(接收容器) byte[] bys = new byte[1024]; DatagramPacket dp = new DatagramPacket(bys, bys.length); // 调用Socket对象接收方法接收数据包 ds.receive(dp); // 获取对方的ip String ip = dp.getAddress().getHostAddress(); // 解析数据 String data = new String(dp.getData(), 0, dp.getLength()); Message message = new Message(); message.obj = data; message.what = 2; handler.sendMessage(message); ds.close(); } catch (Exception e) { e.printStackTrace(); } }
使用Tcp协议传输大文件,循环将数据写入流中(Tcp发送端)
/* * @param path 文件路径 * @param FileName 文件名 */ public void sendFile(String path, String FileName) { DhcpInfo info = wifiManager.getDhcpInfo(); serverAddress = WifiAdmin.intToIp(info.serverAddress); Socket s = new Socket(serverAddress, PORT); OutputStream out = s.getOutputStream(); //将文件名写在流的头部以#分割 out.write((FileName + "#").getBytes()); FileInputStream inputStream = new FileInputStream(new File(path)); byte[] buf = new byte[1024]; int len; //判断是否读到文件末尾 while ((len = inputStream.read(buf)) != -1) { out.write(buf, 0, len);//将文件循环写入输出流 } //告诉服务端,文件已传输完毕 s.shutdownOutput(); //获取从服务端反馈的信息 BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream())); String serverBack = in.readLine(); Log.d("TAG", serverBack); //资源关闭 s.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); } }
大文件传输(Tcp接收端)
public synchronized void receiveFile() { try { ServerSocket ss = new ServerSocket(WifiAdmin.PORT); while (true) { Socket socket = ss.accept(); InputStream in = socket.getInputStream(); int content; //装载文件名的数组 byte[] c = new byte[1024]; //解析流中的文件名,也就是开头的流 for (int i = 0; (content = in.read()) != -1; i++) { //表示文件名已经读取完毕 if (content == '#') { break; } c[i] = (byte) content; } //将byte[]转化为字符,也就是我们需要的文件名 String FileName = new String(c, "utf-8").trim(); //创建一个文件,指定保存路径和刚才传输过来的文件名 OutputStream saveFile = new FileOutputStream( new File(Environment.getExternalStorageDirectory().toString(), FileName)); byte[] buf = new byte[1024]; int len; //判断是否读到文件末尾 while ((len = in.read(buf)) != -1) { saveFile.write(buf, 0, len); } saveFile.flush(); saveFile.close(); //告诉发送端我已经接收完毕 OutputStream outputStream = socket.getOutputStream(); outputStream.write("文件接收成功".getBytes()); outputStream.flush(); outputStream.close(); socket.close(); } } catch (Exception e) { e.printStackTrace(); } }
掌握了Socket的基本传输规则,相信你很快就能写出一个利用局域网让两台设备进行数据传输了。
最后附上Demo下载地址
相关文章推荐
- 局域网内通过UDP协议进行传输接受数据——AsyncUdpSocket
- Android-->UDP协议的Socket数据传输
- 详解Android使用Socket对大文件进行加密传输
- Android与Java 服务器使用Socket协议实现Json数据传输
- android c#.net使用socket进行局域网多文件传输
- Android中使用SharedPreferences进行数据存储及文件操作模式
- socket编程(三)---- UDP协议与传输数据报文
- 基于UDP协议的网络编程(使用DatagramSocket发送接收数据)
- 在android中如何使用UDP和TCP传输
- Android应用开发之使用Socket进行大文件断点上传续传
- Android应用开发之使用Socket进行大文件断点上传续传
- android之使用文件进行数据存储
- Java 使用 TCP 和 UDP 传输文件
- Android中使用SharedPreferences进行数据存储及文件操作模式
- Java 使用 TCP 和 UDP 传输文件
- Android之使用文件进行数据存储
- Java使用Socket进行字符串和图片文件同时传输
- socket编程——TCP/UDP数据传输
- 使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
- socket编程——TCP/UDP数据传输