国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > 【工具向】Android UDP与TCP工具类

【工具向】Android UDP与TCP工具类

来源:程序员人生   发布时间:2016-08-10 13:44:43 阅读次数:2375次

甚么是UDPTCP协议?

请看此篇文章

http://www.360doc.com/content/14/0325/09/1317564_363500997.shtml

 

简单来讲,他们都是两种协议,UDP传输时候不需要建立连接,TCP需要建立连接,同时UDP使用了数据报情势,而TCP使用流模式来进行传输,可靠性上TCP的可靠性远大于UDPUDP不能保证数据的正确性,有可能会出现丢包。

 

举个例子:

用踢球来讲,TCP就是1个人A踢出去另外一个人B接住了,然后另外一个人B又踢给了A

UDP来讲就是1个人A,狠狠地往前开了1脚,然后另外一个人B不知道会不会接到这个球。

 

UDP,TCPsocket是甚么关系?

UDPTCP是两种通讯协议,而Socket是实现他们的API

 

 

开始简单编程:

 

首先我们来看下java中的TCPUDP吧:

 

1.使用TCP来进行网络通讯

 

package tcp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; /** * * <pre> * <p>TCPClient类</p> * * @author WindyStory * ================================= * 开发时间 * 2016年6月28日下午10:12:57 * ================================= * </pre> */ public class TCPClient { // 主机地址 127.0.0.1是本地的地址 public static final String HOST = "127.0.0.1"; // 主机的端口号 端口范围为1~65535,建议使用3000以上的 public static final int PORT = 23333; /** * TCP连接类 * @throws IOException * @throws UnknownHostException */ public static void TCPConn() throws UnknownHostException, IOException{ //建立连接 Socket socket = new Socket(HOST,PORT); //构造InputStream流进行读取 InputStream is = socket.getInputStream(); //构造OutputStream流进行写入数据 OutputStream os = socket.getOutputStream(); //写数据 os.write("Hello,I am Client!".getBytes()); //读取数据 int end = 0; byte[] bs = new byte[1024]; while ((end = is.read(bs)) != ⑴) { System.out.print(new String(bs).trim());//去掉空格 } //使用完以后关闭流 os.close(); is.close(); socket.close(); } public static void main(String[] args) { try { TCPConn(); } catch (IOException e) { e.printStackTrace(); } } }

 

package tcp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * * <pre> * <p>TCPServer类</p> * * @author WindyStory * ================================= * 开发时间 * 2016年6月28日下午10:13:11 * ================================= * </pre> */ public class TCPServer { // 主机的端口号 端口范围为1~65535,建议使用3000以上的 public static final int PORT = 23333; /** * TCP服务端类 * * @throws Exception */ public static void TCPServerConn() throws Exception { // 建立监听 ServerSocket serverSocket = new ServerSocket(PORT); // 获得Socket对象 Socket socket = serverSocket.accept(); // 构造InputStream流进行读取 InputStream is = socket.getInputStream(); // 构造OutputStream流进行写入数据 OutputStream os = socket.getOutputStream(); // 写入 os.write("Hello,I am Server!".getBytes()); // 读取 int end = 0; byte[] bs = new byte[1024]; while ((end = is.read(bs)) != ⑴) { System.out.print(new String(bs).trim());// 去掉空格 } // 关闭流 os.close(); is.close(); socket.close(); serverSocket.close(); } public static void main(String[] args) { try { TCPServerConn(); } catch (Exception e) { e.printStackTrace(); } } }

 

2.使用UDP来进行网络通讯

 

package udp; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * * <pre> * <p>UDPClient类</p> * * @author WindyStory * ================================= * 开发时间 * 2016年6月28日下午10:13:20 * ================================= * </pre> */ public class UDPClient { // 主机地址 127.0.0.1是本地的地址 public static final String HOST = "127.0.0.1"; // 主机的端口号 端口范围为1~65535,建议使用3000以上的 public static final int PORT = 23333; /** * UDP连接类 * * @throws IOException * @throws UnknownHostException */ public static void UDPConn() throws UnknownHostException, IOException { // 构造DatagramSocket DatagramSocket socket = new DatagramSocket(); // 构造DatagramPacket byte[] buf = "Hello,I am Client!".getBytes(); // 构造地址 InetAddress address = InetAddress.getByName(HOST); // 构造发送的数据包 DatagramPacket packet = new DatagramPacket(buf, buf.length, address, PORT); // 发送数据 socket.send(packet); // 读取数据 byte[] recBuf = new byte[1024]; // 构造接收的数据包 DatagramPacket recvPacket = new DatagramPacket(recBuf, recBuf.length); // 接收的数据包 socket.receive(recvPacket); // 接收的数据 System.out.println("Server:" + new String(recvPacket.getData(), 0, recvPacket.getLength())); // 使用完以后关闭流 socket.close(); } public static void main(String[] args) { try { UDPConn(); } catch (IOException e) { e.printStackTrace(); } } }

package udp; import java.io.InputStream; import java.io.OutputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; /** * * <pre> * <p>UDPServer类</p> * * @author WindyStory * ================================= * 开发时间 * 2016年6月28日下午10:13:29 * ================================= * </pre> */ public class UDPServer { // 主机的端口号 端口范围为1~65535,建议使用3000以上的 public static final int PORT = 23333; /** * TCP服务端类 * * @throws Exception */ public static void UDPServerConn() throws Exception { //接收的数据包 DatagramSocket server = new DatagramSocket(PORT); byte[] recvBuf = new byte[1024]; //接收数据 DatagramPacket recvPacket = new DatagramPacket(recvBuf, recvBuf.length); server.receive(recvPacket); System.out.println("Client:" + new String(recvPacket.getData(), 0, recvPacket.getLength())); //同客户端 int port = recvPacket.getPort(); InetAddress addr = recvPacket.getAddress(); String sendStr = "Hello ! I am Server"; byte[] sendBuf; sendBuf = sendStr.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendBuf, sendBuf.length, addr, port); server.send(sendPacket); //关闭流 server.close(); } public static void main(String[] args) { try { UDPServerConn(); } catch (Exception e) { e.printStackTrace(); } } }


Android中使用TCP/UDP

 

android中由于不能使用耗时操作在主UI线程中,所以我们需要使用AsyncTask类来开启异步线程履行网络要求,但是本人在实际项目中,高并发网络要求时,会出现AsyncTask失效的问题,这里建议使用开源的MultiAsynctask.

GitHub地址:

https://github.com/yanzhenjie/MultiAsynctask

 

UDP工具类可使用改文章中的:

http://blog.csdn.net/qinpeng100423/article/details/8980423

这里贴下博主的代码,大家来看下:

import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; /** * Copyright 2007 GuangZhou Cotel Co. Ltd. * All right reserved. * UTP服务类. * @author QPING */ public class UdpServerSocket { private byte[] buffer = new byte[1024]; private DatagramSocket ds = null; private DatagramPacket packet = null; private InetSocketAddress socketAddress = null; private String orgIp; /** * 构造函数,绑定主机和端口. * @param host 主机 * @param port 端口 * @throws Exception */ public UdpServerSocket(String host, int port) throws Exception { socketAddress = new InetSocketAddress(host, port); ds = new DatagramSocket(socketAddress); System.out.println("服务端启动!"); } public final String getOrgIp() { return orgIp; } /** * 设置超时时间,该方法必须在bind方法以后使用. * @param timeout 超时时间 * @throws Exception */ public final void setSoTimeout(int timeout) throws Exception { ds.setSoTimeout(timeout); } /** * 取得超时时间. * @return 返回超时时间. * @throws Exception */ public final int getSoTimeout() throws Exception { return ds.getSoTimeout(); } /** * 绑定监听地址和端口. * @param host 主机IP * @param port 端口 * @throws SocketException */ public final void bind(String host, int port) throws SocketException { socketAddress = new InetSocketAddress(host, port); ds = new DatagramSocket(socketAddress); } /** * 接收数据包,该方法会造成线程阻塞. * @return 返回接收的数据串信息 * @throws IOException */ public final String receive() throws IOException { packet = new DatagramPacket(buffer, buffer.length); ds.receive(packet); orgIp = packet.getAddress().getHostAddress(); String info = new String(packet.getData(), 0, packet.getLength()); System.out.println("接收信息:" + info); return info; } /** * 将响应包发送给要求端. * @param bytes 回应报文 * @throws IOException */ public final void response(String info) throws IOException { System.out.println("客户端地址 : " + packet.getAddress().getHostAddress() + ",端口:" + packet.getPort()); DatagramPacket dp = new DatagramPacket(buffer, buffer.length, packet .getAddress(), packet.getPort()); dp.setData(info.getBytes()); ds.send(dp); } /** * 设置报文的缓冲长度. * @param bufsize 缓冲长度 */ public final void setLength(int bufsize) { packet.setLength(bufsize); } /** * 取得发送回应的IP地址. * @return 返回回应的IP地址 */ public final InetAddress getResponseAddress() { return packet.getAddress(); } /** * 取得回应的主机的端口. * @return 返回回应的主机的端口. */ public final int getResponsePort() { return packet.getPort(); } /** * 关闭udp监听口. */ public final void close() { try { ds.close(); } catch (Exception ex) { ex.printStackTrace(); } } /** * 测试方法. * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String serverHost = "127.0.0.1"; int serverPort = 3344; UdpServerSocket udpServerSocket = new UdpServerSocket(serverHost, serverPort); while (true) { udpServerSocket.receive(); udpServerSocket.response("你好,sterning!"); } } }


 

可是博主没有写TCP的工具,TCP连接时候不能像UDP1样,可以随时new,经过实战项目发现,new屡次以后会使绑定的地址生成多个,所以必须使用单例模式来保证我们new的TCP类的唯1性,好了,我们来造1个轮子吧,空话少说直接上代码:

 

package com.windystory.battlefield.net; import android.util.Log; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; public class TCPUtils { //端口号 public static final int PORT = 9090; //地址 public static final String HOST = "192.168.0.100"; private byte[] buffer = new byte[1024]; public static Socket socket; //Double CheckLock(DCL模式单例) private static TCPUtils utils = null; public static TCPUtils getInstance() { if (utils == null) { synchronized(TCPUtils.class){ if (utils == null) { utils = new TCPUtils(); } } } return utils; } /** * 构造函数,创建TCP客户端 */ private TCPUtils() { try { socket = new Socket(HOST, PORT); } catch (IOException e) { e.printStackTrace(); } } /** * 设置超时时间,该方法必须在bind方法以后使用. * * @param timeout 超时时间 * @throws Exception */ public void setSoTimeout(final int timeout) throws Exception { socket.setSoTimeout(timeout); } /** * 取得超时时间. * * @return 返回超时时间 * @throws Exception */ public int getSoTimeout() throws Exception { return socket.getSoTimeout(); } public final Socket getSocket() { return socket; } /** * 向指定的服务端发送数据信息. * * @param data 发送的数据信息 * @return 返回构造后俄数据报 * @throws IOException */ public final OutputStream send( String data) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); OutputStream outputStream = socket.getOutputStream(); if (data != null) { outputStream.write(data.getBytes()); } return outputStream; } /** * 接收从指定的服务端发回的数据. * * @return 返回从指定的服务端发回的数据. * @throws Exception */ public final String receive() throws Exception { try { InputStream inputStream = socket.getInputStream(); DataInputStream input = new DataInputStream(inputStream); byte[] b = new byte[10000]; while (true) { int length = input.read(b); String Msg = new String(b, 0, length, "gb2312"); Log.v("data", Msg); return Msg; } } catch (Exception ex) { ex.printStackTrace(); } return ""; } /** * 关闭tcp连接. */ public void close() { try { socket.close(); } catch (Exception ex) { ex.printStackTrace(); } } }

 使用时候可使用以下代码:

new MultiAsynctask<Void, Void, Void>() { @Override public Void onTask(Void... voids) { try { TCPUtils.getInstance().send(".......");//发送 } catch (Exception e) { e.printStackTrace(); } return null; } }.execute();


 好了,就是这样,注意需要访问网络加入权限:

<uses-permission android:name=”android.permission.INTERNET”/>

Demo地址下载


生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生