Here is a method which will send a message to a quake server. The message type can be either a control message or a game message.It returns a byte array containing the server response. If the 50 ms timeout elapses, then it returns a byte array of length 0.
static final int CONTROLMSG=0;
static final int GAMEMSG=1;
int clientPktNum=0;
int serverPktNum=0;
byte[] sendPacket(int type, byte[] command)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
byte[] message;
if(type == CONTROLMSG)
{
bOut.write(CTRLheader, 0, CTRLheader.length);
bOut.write(command, 0, command.length);
message = bOut.toByteArray();
}
else //GAME MESSAGE
{
//assemble packet numbers
String hexCode;
int cNumber;
byte [] cPktNumber = {(byte)0, (byte)0, (byte)0, (byte)0};
byte [] sPktNumber = {(byte)0, (byte)0, (byte)0, (byte)0};
//check toggle bit
if(bit31)
{
cNumber = clientPktNum | 0x80000000;
bit31=false;
}
else
cNumber = clientPktNum;
//little-ending (reverse byte order)
cPktNumber[3] = (byte)((cNumber >>> 24) & 0xFF);
cPktNumber[2] = (byte)((cNumber >>> 16) & 0xFF);
cPktNumber[1] = (byte)((cNumber >>> 8) & 0xFF);
cPktNumber[0] = (byte)((cNumber >>> 0) & 0xFF);
sPktNumber[3] = (byte)((serverPktNum >>> 24) & 0xFF);
sPktNumber[2] = (byte)((serverPktNum >>> 16) & 0xFF);
sPktNumber[1] = (byte)((serverPktNum >>> 8) & 0xFF);
sPktNumber[0] = (byte)((serverPktNum >>> 0) & 0xFF);
bOut.write(cPktNumber, 0, cPktNumber.length);
bOut.write(sPktNumber, 0, sPktNumber.length);
bOut.write(command, 0, command.length);
message = bOut.toByteArray();
clientPktNum++;
}
DatagramPacket dpQuery = new DatagramPacket(message, message.length,
serverAddress, port);
byte[] serverResponse= new byte[1024]; //set a default length
DatagramPacket dpAnswer = new DatagramPacket(serverResponse,
serverResponse.length);
DatagramSocket dSocket = null;
boolean packetNotReceived = false;
try
{
dSocket = new DatagramSocket();
dSocket.setSoTimeout(50);
dSocket.send(dpQuery);
dSocket.receive(dpAnswer);
}
catch (InterruptedIOException iioe)
{ iioe.printStackTrace();
//handle socket timeout
packetNotReceived = true;
}
catch (SocketException se)
{ se.printStackTrace();
packetNotReceived = true;
}
catch (IOException ioe)
{ System.out.println("can't send packet!");
ioe.printStackTrace();
packetNotReceived = true;
}
finally
{
if(dSocket!=null)
dSocket.close();
}
int responseLength = dpAnswer.getLength();
byte[] result=new byte[0];
if(!packetNotReceived)
{
result = new byte[responseLength];
for(int i=0; i < responseLength; i++)
result[i]= serverResponse[i];
if(type == GAMEMSG)
serverPktNum++;
}
return result;
}