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下载地址

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. Android高性能编码 - 第八篇 移动端安全规范
  3. 说说Android的MVP模式
  4. android 空调遥控器——简单发送内容
  5. Android(安卓)Studio实现简单的购物商城界面
  6. Android(安卓)中 MVC 的简单理解
  7. android 解析并显示dicom文件的数据和图像
  8. Android报表解决方案 使用开源组件iChartjs(二)
  9. Unity3D 游戏引擎之游戏场景的切换与持久化简单数据的储存(十四)

随机推荐

  1. Android面试系列文章2018之Android部分In
  2. Android(安卓)中ContentProvider的实例详
  3. 推荐一个Android的在线课程
  4. android:layout_gravity和gravity的区别
  5. android binder机制之--(创建binder服务)
  6. 我眼中的Android(安卓)IDE
  7. android技术要点梳理
  8. Android启动脚本init.rc
  9. andorid padding margin
  10. Android性能调优工具TraceView介绍