TCP:Transmission Control
Protocol 传输控制协议
UDP 是User Datagram
Protocol 用户数据包协议
项目中遇到一个需求,需要在IPhone或者Android手机设备模拟手柄,在屏幕上绘制手柄按键、摇杆甚至鼠标等,然后通过WIFI和安卓电视的服务端连接起来,实现电视上的游戏和手机的上行、下行数据通路。
采取的做法是手机端发送UDP广播,电视UDP服务端收到后通过UDP单点通信,返回信息给手机端。手机端再和服务端创建TCP连接。
代码片段:
private static final String MULTICASTHOST = "239.255.255.255";
private static final int PORT = 5858;private static final String CLIENT_SOCKET_TYPE_NORMAL = "normal";
private static final String CLIENT_SOCKET_TYPE_CLOSE = "close";
/**
* UDP server
* @author siyuan
*
*/
private class UDPMulticastServer implements Runnable {
private MulticastSocket multicastSocket;
private InetAddress receiveAddress;public UDPMulticastServer() {
try {
multicastSocket = new MulticastSocket(PORT);
receiveAddress = InetAddress.getByName(MULTICASTHOST);
multicastSocket.joinGroup(receiveAddress);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}@Override
public void run() {
byte buf[] = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
while (true) {
try {
multicastSocket.receive(dp);
String info = new String(buf, 0, dp.getLength());
// 1、判断非自己的IP,则是服务端IP
printLog("接收: " + dp.getAddress());
parseData(dp, info);
} catch (Exception e) {
e.printStackTrace();
multicastSocket.close();
}
}
}
}
/**
* UDP 点对点* @param message
*/
private void sendUDPP2PMessage (String message) {
try {
InetAddress serverAddr = InetAddress.getByName(remoteIPAddress);
DatagramSocket socket = new DatagramSocket();
byte[] buf = message.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length,
serverAddr, PORT);
socket.send(packet);
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* tcp 服务端
* @author siyuan
*
*/
private class TCPServer implements Runnable {
private boolean isTCPSocketConnecting = false;
private int lastButtonValue = 0;@Override
public void run() {
byte buf[] = new byte[1024];
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(PORT);
while (true) {
socket = serverSocket.accept();
// 等待客户端连接
printLog("serverSocket wait");
isTCPSocketConnecting = true;while(isTCPSocketConnecting) {
InputStream inputStream = socket.getInputStream();
inputStream.read(buf);
String info = new String(buf, "utf-8");String[] data = info.split("=");
JSONObject requestJO = null;
try {
requestJO = new JSONObject(data[1]);
} catch (JSONException e) {
e.printStackTrace();
}if(requestJO != null) {
if(CLIENT_SOCKET_TYPE_NORMAL.equals(requestJO.opt("status"))) {
if(data[1].contains("button")) {
//按钮
parseKeyEvent(requestJO);
} else if(data[1].contains("motion")) {
//摇杆
parseMotionEvent(requestJO);
}
} else if(CLIENT_SOCKET_TYPE_CLOSE.equals(requestJO.opt("status"))) {
isTCPSocketConnecting = false;
continue;
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
serverSocket.close();isTCPSocketConnecting = false;
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* tcp 点对点通信
* @param message
*/
private void sendTCPMessage(String message) {
Socket socket = null;
try { //TCP服务器IP地址
InetAddress serverAddr = InetAddress.getByName(remoteIPAddress);
socket = new Socket(serverAddr, PORT);
PrintWriter out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),true);
out.println(message);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}