Android编程:UDP客户端和TCP客户端
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN10
开发环境:Android Studio 2.2 Preview 3
说明:
1.服务器的IP和端口固定,分别编写UDP和TCP客户端。
2.Android中主线程不允许网络操作,所以用线程实现UDP和TCP的收发。
3.用JAVA内置的观察者模式处理接收数据,如果接收到数据,则通知观察者。
4.Socket_Audio.java为UDP客户端
5.Socket_Cmd.java为TCP客户端
源码:
Socket_Audio.java
package com.bazhangkeji.demo01;
/**
* @file Socket_Audio.java
* @brief 语音端口类
* @author jdh
* @date 2016/7/9
* @update 2016/7/10
*/
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Observable;
public class Socket_Audio extends Observable implements Runnable {
//常量
//服务器IP
private final String SERVER_IP = "115.28.86.171";
//语音端口
private final int SERVER_PORT_AUDIO = 12801;
//本地端口
private final int LOCAL_PORT_AUDIO = 12801;
//网络相关变量
//最大帧长
private static final int MAX_DATA_PACKET_LENGTH = 1024;
//接收数据缓存
private byte[] Buffer_Receive = new byte[MAX_DATA_PACKET_LENGTH];
// private StringBuilder Frame_Receive = new StringBuilder(MAX_DATA_PACKET_LENGTH);
//接收数据包
private DatagramPacket Packet_Receive;
//端口
private DatagramSocket Udp_Socket;
/**
* @brief 构造函数
*/
public Socket_Audio()
{
try
{
//端口
Udp_Socket = new DatagramSocket(LOCAL_PORT_AUDIO);
//接收包
Packet_Receive = new DatagramPacket(Buffer_Receive, MAX_DATA_PACKET_LENGTH);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/**
* @brief 发送数据
* @param data:需要发送的数据
* @param len:数据字节数据
*/
public void send(byte[] data, int len)
{
Thread_Send thread_send = new Thread_Send(data, len);
new Thread(thread_send).start();
}
@Override
public void run() {
while (true)
{
try
{
//接收数据
Udp_Socket.receive(Packet_Receive);
// //打印接收数据
// System.out.println(new String(Buffer_Receive,0,Packet_Receive.getLength()));
//判断数据是否合法
InetSocketAddress address = (InetSocketAddress) Packet_Receive.getSocketAddress();
//判断是否是调度服务器的ip
if (!address.getHostName().equals(SERVER_IP))
{
continue;
}
//判断是否是调度服务器的端口
if (address.getPort() != SERVER_PORT_AUDIO)
{
continue;
}
//通知观察者
setChanged();
notifyObservers(Packet_Receive);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* @brief 发送线程
*/
private class Thread_Send implements Runnable {
//发送数据缓存
private byte[] Buffer_Send = new byte[MAX_DATA_PACKET_LENGTH];
//发送数据包
private DatagramPacket Packet_Send;
/**
* @brief 构造函数
* @param data:需要发送的数据
* @param len:数据字节数据
*/
public Thread_Send(byte[] data, int len) {
//发送包
Packet_Send = new DatagramPacket(Buffer_Send, MAX_DATA_PACKET_LENGTH);
Packet_Send.setData(data);
Packet_Send.setLength(len);
}
@Override
public void run() {
try {
Packet_Send.setPort(SERVER_PORT_AUDIO);
Packet_Send.setAddress(InetAddress.getByName(SERVER_IP));
Udp_Socket.send(Packet_Send);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Socket_Cmd.java
package com.bazhangkeji.demo01;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Observable;
import java.util.Observer;
/**
* @file Socket_Cmd.java
* @brief 信令端口类
* @author jdh
* @date 2016/7/9
* @update 2016/7/10
*/
public class Socket_Cmd extends Observable implements Runnable {
//常量
//服务器IP
private final String SERVER_IP = "115.28.86.171";
//语音端口
private final int SERVER_PORT_CMD = 12800;
//本地端口
private final int LOCAL_PORT_CMD = 12800;
//网络相关变量
//最大帧长
private static final int MAX_DATA_PACKET_LENGTH = 1024;
//端口
Socket Tcp_Socket;
//输入流
InputStream Buffer_Receive_Stream;
//网络连接标志
private boolean Flag_Connect = false;
//接收数据缓存
private byte[] Buffer_Receive = new byte[MAX_DATA_PACKET_LENGTH];
//接收数据包
private DatagramPacket Packet_Receive;
/**
* @brief 构造函数
*/
public Socket_Cmd() {
//接收包
Packet_Receive = new DatagramPacket(Buffer_Receive, MAX_DATA_PACKET_LENGTH);
}
/**
* @brief 发送数据
* @param data:需要发送的数据
* @param len:数据字节数据
*/
public synchronized void send(final byte[] data, final int len) {
//判断是否连接服务器
if (!Flag_Connect) {
return;
}
//发送
Thread_Send thread_send = new Thread_Send(data, len);
new Thread(thread_send).start();
}
@Override
public void run() {
//连接服务器
//端口
try {
Tcp_Socket = new Socket(SERVER_IP, SERVER_PORT_CMD);
Buffer_Receive_Stream = Tcp_Socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
//开启监听线程
try
{
new Thread(new Runnable(){
@Override
public void run() {
while (true) {
//判断当前是否连接
if (!Flag_Connect)
{
continue;
}
//监听
try {
if (Buffer_Receive_Stream.available() > 0)
{
Packet_Receive.setLength(Buffer_Receive_Stream.read(Packet_Receive.getData()));
// System.out.println(new String(Packet_Receive.getData(),0,Packet_Receive.getLength()));
//通知观察者
setChanged();
notifyObservers(Packet_Receive);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
catch (Exception e)
{
e.printStackTrace();
}
//检测连接状态
while (true) {
Flag_Connect = Tcp_Socket.isConnected();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println("连接状态:" + Flag_Connect);
if (!Flag_Connect) {
SocketAddress address = new InetSocketAddress(SERVER_IP, SERVER_PORT_CMD);
try {
Tcp_Socket.connect(address);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @brief 发送线程
*/
private class Thread_Send implements Runnable {
//输出流
OutputStream Buffer_Send;
//发送数据缓存
private byte[] Buf_Send = new byte[MAX_DATA_PACKET_LENGTH];
private int Len = 0;
/**
* @brief 构造函数
* @param data:需要发送的数据
* @param len:数据字节数据
*/
public Thread_Send(byte[] data, int len) {
Len = len;
for (int i = 0;i < Len;i++) {
Buf_Send[i] = data[i];
}
//输出流
try {
Buffer_Send = Tcp_Socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
Buffer_Send.write(Buf_Send,0,Len);
Buffer_Send.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
发送示例代码:
Socket_Audio socket_audio = new Socket_Audio();
new Thread(socket_audio).start();
// String buf = "hello,i am jdh1";
// socket_audio.send(buf.getBytes(),buf.length());
for (int i = 0;i < 20;i++)
{
String buf1 = "UDP:I AM JDH" + i;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
socket_audio.send(buf1.getBytes(),buf1.length());
}
Socket_Cmd socket_cmd = new Socket_Cmd();
new Thread(socket_cmd).start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0;i < 20;i++)
{
String buf1 = "TCP:I AM JDH" + i;
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
socket_cmd.send(buf1.getBytes(),buf1.length());
}