[英]Java DatagramSocket time-out but in fact received
我使用WireShark測試結果很奇怪,結果表明我的代碼可以通過套接字成功發送消息。 但是,即使我從服務器收到消息,我的程序也會拋出Timeout
異常。
我不知道為什么會有超時問題。
我的代碼很簡單:
static Timer timer = new Timer();
try {
DatagramSocket c = new DatagramSocket();
c.setBroadcast(true);
byte[] sendData = "messageToServer".getBytes();
try {
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("255.255.255.255"), 10000);
c.connect(InetAddress.getByName("255.255.255.255"), 10000);
c.send(sendPacket);
} catch(Exception ex) {
System.out.println(ex.toString());
}
timer.schedule(new receiveTask(), 2000);
} catch(Exception ex) {
System.out.println(ex.toString());
}
我使用計時器來延遲從服務器接收消息。
receiveTask
類如下所示:
public class receiveTask extends TimerTask {
@Override
public void run() {
// TODO Auto-generated method stub
try {
DatagramSocket c2 = new DatagramSocket();
c2.setSoTimeout(10000);
byte[] recvBuf = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
String message = "";
while (true) {
c2.receive(receivePacket);
System.out.println("Receive packet from Server");
message=new String(receivePacket.getData()).trim();
System.out.println(message);
System.out.println("Close the connection of server socket");
}
} catch(Exception ex) {
System.out.println(ex.toString());
}
}
}
並且在receiveTask
類中引發SocketTimeOut
異常。
由於服務器可以向我發送消息(在WireShark中進行了測試),因此我認為該實現不是在服務器端。 但是什么原因導致超時呢?
為什么服務器向我返回一條消息,但我的程序無法接收到該消息?
我的Java版本是7,在我的計算機上禁用防火牆沒有區別。
任何建議將被認真考慮!
編輯:雖然問題不是關於socket.close(); 我刪除了代碼。
您可以嘗試一些方法。
首先,嘗試調用timer.schedule(new receiveTask(), 2000);
較早,以便您的receiveTask
准備好在發送任何消息之前接收消息。
其次,將c.close()
語句移至finally
子句,尤其是receiveTask
的while
循環中的那receiveTask
以確保您的套接字不會過早關閉。 所以代碼看起來像
DatagramSocket c2 = null;
try{
c2 = new DatagramSocket();
c2.setSoTimeout(10000);
byte[] recvBuf = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(recvBuf, recvBuf.length);
String message = "";
while(true){
c2.receive(receivePacket);
System.out.println("Receive packet from Server");
message=new String(receivePacket.getData()).trim();
System.out.println(message);
System.out.println("Close the connection of server socket");
}
}catch(Exception ex){
System.out.println(ex.toString());
} finally{
if(c2 != null)
c2.close();
}
如果所有其他方法均失敗,請嘗試c2.setSoTimeout(0);
這將導致超時設置為infinite 。 但是我感覺這只是掩蓋真正問題的技巧。
感謝大家的幫助! 我問我的同事,我應該采取另一種方法:打開我自己的服務器部分以接收返回的消息。
我從其他人那里聽說java可能無法正確接收返回消息(也許這就是我總是超時的原因!),因為發送部分還可以,所以只需打開一個有關偵聽包的服務器部分,我就可以從我也要服務器!
請注意,您應該使用目標服務器的相同端口,因此您也將獲得自己發送的軟件包。 只需過濾程序的發送地址即可。
服務器端和完整的概念是這樣的:
static DatagramSocket socket2;
public static void main(String[] args) {
// TODO Auto-generated method stub
// Open my own server part to listen messages from broadcast returned
listen();
// Sending UDP broadcast in this part as question implied
}
public static void listen() {
new Thread() {
public void run() {
try{
socket2 = new DatagramSocket(10000);
socket2.setBroadcast(true);
byte[] recvBuf = new byte[1024];
while (true) {
DatagramPacket packet2 = new DatagramPacket(recvBuf, recvBuf.length);
try{
socket2.receive(packet2);
System.out.println("Discovery packet received from: " + packet2.getAddress().getHostAddress());
System.out.println("Packet received; data: " + new String(packet2.getData()));
String message = new String(packet2.getData());
System.out.println("Received: "+message);
}catch(Exception ex){
System.out.println("Cannot receive package: " + ex.getMessage());
}
}
}catch(Exception ex){
socket2.close();
System.out.println("Server side problem occured: " + ex.getMessage());
}
}
}.start();
}
盡管您可能會注意到代碼相似,但是概念不同。
我認為,發現問題要比僅找到解決問題的方法更好!
如果我的看法是錯誤的,希望有人可以糾正它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.