前段时间做的一个android项目需要通过socket 的UDP协议与机顶盒通信,自己在网上找了很多资料才将其解决,现在将我的解决方法做一下总结:
socket服务端:
/**
* UDP服务类
*/
@SuppressLint("HandlerLeak")
@SuppressWarnings("unused")
public class UdpServerSocket extends Service {
private byte[] buffer = new byte[1024];
private static DatagramSocket ds = null;
private static DatagramSocket dsSocket = null;
private DatagramPacket packet = null;;
private InetSocketAddress socketAddress = null;
private UdpServerSocket udpServerSocket;
private int serverPort = 7001;
private Context mContext;
private ControlBroadcastReceiver receiver;
private static Object DATA_LOCK = new Object();
public UdpServerSocket() {
}
/**
* 监听7001端口,等待接收客服端传过来的信息
*/
public void startUdpSocketServer() {
new Thread() {
public void run() {
synchronized (DATA_LOCK) {
try {
udpServerSocket = new UdpServerSocket();
while (true) {
//这是一个阻塞方法,等待7001口的数据
packet = receive(serverPort);
String info = new String(packet.getData(), 0,
packet.getLength(), "gb18030");
if (info != null) {
//接收到信息,向客服端发送消息
response(info,packet);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
;
}
}.start();
}
/**
* 构造函数,绑定主机和端口
*/
public UdpServerSocket(int port) {
socketAddress = new InetSocketAddress(port);
try {
ds = new DatagramSocket(socketAddress);
} catch (SocketException e) {
Log.i("UdpServerSocket", "UdpServerSocket SocketException ----->"
+ e);
e.printStackTrace();
}
}
/**
* 接收数据包,该方法会造成线程阻塞
*/
public final DatagramPacket receive(int port) {
InetSocketAddress address = new InetSocketAddress(port);
DatagramSocket socket = null;
DatagramPacket p = null;
p = new DatagramPacket(buffer, buffer.length);
try {
socket = new DatagramSocket(address);
socket.receive(p);
if (socket != null) {
socket.close();
}
} catch (IOException e) {
Log.i("receive", "receive IOException ----->" + e);
e.printStackTrace();
}
return p;
}
/**
* 将响应包发送给请求端
*/
public void response(String info, DatagramPacket pack) {
DatagramSocket socket = null;
DatagramPacket dp;
try {
socket = new DatagramSocket();
dp = new DatagramPacket(info.getBytes("gb18030"),
info.getBytes("gb18030").length, pack.getAddress(), 7002);
socket.send(dp);
if (socket != null) {
socket.close();
}
} catch (UnsupportedEncodingException e1) {
Log.i("response", "responese UnsupportedEncodingException ----->"
+ e1);
e1.printStackTrace();
} catch (IOException e) {
Log.i("response", "responese IOException ----->" + e);
e.printStackTrace();
}
/*if (packet != null) {
packet = null;
}*/
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
mContext = UdpServerSocket.this;
startUdpSocketServer();
} catch (Exception e) {
e.printStackTrace();
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
socket客服端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import android.util.Log;
import com.ycsoft.android.h5moviebar.comment.Constants;
public class UDPClient {
/**
* 默认请求参数
*/
private int sendPort = 7001;// 发送端口
private int receivePort = 7002;// 接收端口
private byte[] buffer = new byte[8*1024];
public static final String ERROR_RESULT = "KONE_UDP_OBTAIN_DATA_OP_NO";
/**
* 发送信息到服务器并接收
*/
public String sendAndRec(String msg) {
String result;
try {
result = receiveMsg(msg);
} catch (Exception e) {
e.printStackTrace();
result = ERROR_RESULT;
}
return result;
}
void sendMsg(String msg) throws Exception {
DatagramSocket dSocket = null;
InetAddress local = null;
local = InetAddress.getByName(Constants.FTP_ADRESS);
dSocket = new DatagramSocket();
int msg_len = 0;
msg_len = msg == null ? 0 : msg.getBytes("gb18030").length;
int sPort = sendPort;
DatagramPacket sendPacket = null;
sendPacket = new DatagramPacket(msg.getBytes("gb18030"), msg_len,
local, sPort);
dSocket.send(sendPacket);
if (dSocket != null) {
dSocket.close();
}
}
String receiveMsg(String msg) throws Exception {
String result = "";
DatagramSocket dSocket = new DatagramSocket(null);
dSocket.setReuseAddress(true);
dSocket.bind(new InetSocketAddress(receivePort));
dSocket.setSoTimeout(2000);
DatagramPacket recPacket = new DatagramPacket(buffer, buffer.length);
sendMsg(msg);
try {
dSocket.receive(recPacket);
if (recPacket.getLength() > 0) {
result = new String(recPacket.getData(), 0,
recPacket.getLength(), "gb18030");
Log.i("msg", "返回正确结果:" + result);
}
if (dSocket != null) {
dSocket.close();
}
} catch (IOException e) {
result = "false";
e.printStackTrace();
}
return result;
}
}
在发送和接收的时候主要要注意每次请求的时候请求完了要情况pack里面的内容,否则就会出现服务端会记住客服端每次发过来的包,并每次一并发送给客户端。