UDP搜索
服务器端
TCP口令
package constants;
/**
* TCP不变的量
* Created by 007 on 2020/7/8.
*/
public class TCPConstants {
//服务器固化UDP接收端口
public static int PORT_SERVER = 30401;
}
UDP口令
package constants;
/**
* UDP不变的量
* Created by 007 on 2020/7/8.
*/
public class UDPConstants {
//公用头部
public static byte[] HEADER = new byte[]{7,7,7,7,7,7,7,7};
//服务器固化UDP接收端口
public static int PORT_SERVER = 30201;
//客户端回送端口
public static int PORT_CLIENT_RESPONSE = 30202;
}
服务器端Server
package server;
import constants.TCPConstants;
import java.io.IOException;
/**
* 服务器端
* Created by 007 on 2020/7/8.
*/
public class Server {
public static void main(String[] args){
ServerProvider.start(TCPConstants.PORT_SERVER);
try{
System.in.read();
}catch (IOException e){
e.printStackTrace();
}
ServerProvider.stop();
}
}
ServerProvider类
package server;
import clink.net.qiujuer.clink.utils.ByteUtils;
import constants.UDPConstants;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
import java.util.UUID;
/**
* UDP服务器提供者
* Created by 007 on 2020/7/8.
*/
public class ServerProvider {
private static Provider PROVIDER_INSTANCE; //单例
static void start(int port){
stop();
String sn = UUID.randomUUID().toString();
Provider provider = new Provider(sn,port);
provider.start();
PROVIDER_INSTANCE = provider;
}
//单例模式
static void stop(){
if (PROVIDER_INSTANCE != null){
PROVIDER_INSTANCE.exit();
PROVIDER_INSTANCE = null;
}
}
private static class Provider extends Thread{
private final byte[] sn;
private final int port;
private boolean done = false;
private DatagramSocket ds = null;
//存储消息的Buffer
final byte[] buffer = new byte[128];
Provider(String sn,int port){
super();
this.sn = sn.getBytes();
this.port = port;
}
@Override
public void run(){
super.run();
System.out.println("UDPProvider Started.");
try{
//监听端口
ds = new DatagramSocket(UDPConstants.PORT_SERVER);
//接受消息的Packet
DatagramPacket receivePack = new DatagramPacket(buffer,buffer.length);
while(!done){
//接收
ds.receive(receivePack);
// 打印接收到的信息与发送者的信息
// 发送者的IP地址
String clientIp = receivePack.getAddress().getHostAddress();
int clientPort = receivePack.getPort();
int clientDataLen = receivePack.getLength();
byte[] clientData = receivePack.getData();
boolean isValid = clientDataLen >= (UDPConstants.HEADER.length + 2 + 4)
&& ByteUtils.startsWith(clientData, UDPConstants.HEADER);
System.out.println("ServerProvider receive form ip:" + clientIp
+ "\tport:" + clientPort + "\tdataValid:" + isValid);
if (!isValid){
//无效继续
continue;
}
// 解析命令与回送端口
int index = UDPConstants.HEADER.length;
short cmd = (short) ((clientData[index++] << 8) | (clientData[index++] & 0xff));
int responsePort = (((clientData[index++]) << 24) |
((clientData[index++] & 0xff) << 16) |
((clientData[index++] & 0xff) << 8) |
((clientData[index] & 0xff)));
// 判断合法性
if (cmd == 1 && responsePort > 0) {
// 构建一份回送数据
ByteBuffer byteBuffer = ByteBuffer.wrap(buffer);
byteBuffer.put(UDPConstants.HEADER);
byteBuffer.putShort((short) 2);
byteBuffer.putInt(port);
byteBuffer.put(sn);
int len = byteBuffer.position();
// 直接根据发送者构建一份回送信息
DatagramPacket responsePacket = new DatagramPacket(buffer,
len,
receivePack.getAddress(),
responsePort);
ds.send(responsePacket);
System.out.println("ServerProvider response to:" + clientIp + "\tport:" + responsePort + "\tdataLen:" + len);
} else {
System.out.println("ServerProvider receive cmd nonsupport; cmd:" + cmd + "\tport:" + port);
}
}
}catch (IOException ignored) {
} finally {
close();
}
}
private void close(){
if (ds != null){
ds.close();
ds = null;
}
}
/**
* 提供结束
* */
void exit(){
done = true;
close();
}
}
}
ByteUtils工具类
package clink.net.qiujuer.clink.utils;
/**
* 字节工具
* Created by 007 on 2020/7/9.
*/
public class ByteUtils {
public static boolean startsWith(byte[] source, byte[] match) {
return startsWith(source, 0, match);
}
public static boolean startsWith(byte[] source,int offset,byte[] match){
if (match.length>(source.length-offset)){
return false;
}
for (int i=0;i<match.length;i++){
if(source[offset+i] != match[i]){
return false;
}
}
return true;
}
public static boolean equals(byte[] source,byte[] match){
if (match.length != source.length){
return false;
}
return startsWith(source,0,match);
}
public static void getBytes(byte[] source,int srcBegin,int srcEnd,
byte[] destination,int dstBegin){
System.arraycopy(source,srcBegin,destination,dstBegin,srcEnd-srcBegin);
}
public static byte[] subbytes(byte[] source,int srcBegin,int srcEnd){
byte destinatio