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

什么是UDPTCP协议?

请看此篇文章

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

 

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

 

举个例子:

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

UDP来说就是一个人A,狠狠地往前开了一脚,然后另一个人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)) != -1) {
			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)) != -1) {
			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连接时候不能像UDP一样,可以随时new,经过实战项目发现,new多次以后会使绑定的地址生成多个,所以必须使用单例模式来保证我们new的TCP类的唯一性,好了,我们来造一个轮子吧,废话少说直接上代码:

 

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

Android学习交流群:523487222

(如果您觉得有用,欢迎加入,一起学习进步)
点击链接加入群【Android学习群】


  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
安卓UDP媒体流在线调试工具是一种用于调试和测试安卓设备上UDP媒体流的工具。它可以帮助开发人员在开发过程中实时监控和调试媒体流的传输情况,以确保其正常工作。 该工具具有以下主要功能: 1. 数据包捕获和分析:工具可以捕获设备上的UDP数据包,并提供详细的分析和统计信息,例如数据包的大小、传输时间、丢包率等。这些信息能够帮助开发人员判断媒体流传输是否正常。 2. 调试日志记录:工具可以记录设备上的调试日志,包括错误信息、异常情况等。通过查看这些日志,开发人员可以了解到媒体流传输过程中可能出现的问题,并进行相应的调试和修复。 3. 传输控制和模拟:工具可以模拟不同的网络环境,例如高延迟、低带宽等,以帮助开发人员测试媒体流的适应性和稳定性。此外,工具还提供传输控制功能,允许开发人员暂停、恢复或重新开始媒体流的传输,以便进行特定场景的调试和测试。 4. 报告和分析:工具可以生成详细的报告和分析数据,包括媒体流的性能指标、错误统计等。这些报告能够提供给开发团队和相关利益相关方,以便他们评估媒体流的质量和性能。 总之,安卓UDP媒体流在线调试工具是一种强大的工具,可以帮助开发人员更好地调试和测试安卓设备上的UDP媒体流。它提供了丰富的功能和工具,用于监控、分析和模拟媒体流的传输,从而确保其正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值