게임 서버 정보를 읽는 Java 응용 프로그램을 작성하고 있습니다. 그게 전부이며, 같은 일을하는 루프에서 돌아갑니다.Java DatagramSocket은 몇 번의 실행 후 SocketTimeoutException을 throw합니다.
문제는 처음에 잘 작동한다는 것입니다. 응답이 있습니다. 일부 (상수가 아닌) 시간이 지나면 SocketTimeoutException을 던지기 시작합니다.
이것은 SAMP 서버를 쿼리하는 데 사용하는 방법입니다.
private ByteBuffer sendQuery(char opcode) throws IOException {
ByteBuffer bf = ByteBuffer.allocate(11);
bf.order(ByteOrder.LITTLE_ENDIAN);
bf.put("SAMP".getBytes("US-ASCII"));
bf.put(encodeIP(getIp()));
bf.putShort((short)getPort());
bf.put((byte)opcode);
Logger.getLogger().log("Request to " + this.getAddress().getHostString() + ":"+ByteConvert.bytesToHexString(bf.array()));
DatagramPacket packet = new DatagramPacket(bf.array(), bf.capacity(), getAddress().getAddress(), getPort());
getSocket().send(packet);
byte[] buffer = new byte[4096];
packet = new DatagramPacket(buffer, buffer.length, getAddress().getAddress(), getPort());
getSocket().receive(packet);
if(packet.getLength() > 4096)
Logger.getLogger().log("Large packet received from " + this.getIp() + " :"+packet.getLength());
bf = ByteBuffer.allocate(packet.getLength());
bf.order(ByteOrder.LITTLE_ENDIAN);
bf.put(buffer, 0, packet.getLength());
bf.flip();
return bf;
}
encodeIP
있어서, 상기 프로토콜을 설명한다 here
private static byte[] encodeIP(String s) throws IOException {
String[] ip = s.split("\\.");
byte[] bytes = new byte[ip.length];
for(int i = 0; i < ip.length; i++) {
bytes[i] = (byte)Integer.parseInt(ip[i]);
}
return bytes;
}
.
다른 게임의 경우 동일한 문제가 있지만 현재 SAMP에 대한 조사는 프로토콜이 가장 단순한 것으로 보입니다.
응용 프로그램이 Linux, Debian 7.0에서 실행됩니다. 방화벽을 완전히 비활성화하려고했습니다.
getSocket() 메서드는 이전에 만들어진 소켓을 반환합니까, 아니면 지속적으로 새로운 소켓을 생성합니까? – ControlAltDel
항상 동일한 소켓을 반환합니다. 나는 생성자에서 소켓을 생성하고'getSocket()'이 그것을 반환한다. – Bebras