2017-06-01 160 views
1

我有一個本地Memcached實例並試圖通過基本的Java TCP和UDP套接字API訪問它。 TCP客戶端工作正常,但UDP客戶端總是拋出異常。在Memcached的Java UDP套接字客戶端中接收超時

java.net.SocketTimeoutException: Receive timed out 
at java.net.PlainDatagramSocketImpl.receive0(Native Method) 
    at java.net.AbstractPlainDatagramSocketImpl.receive(AbstractPlainDatagramSocketImpl.java:144) 
    at java.net.DatagramSocket.receive(DatagramSocket.java:812) 
    at test.Test.udp(Test.java:71) 
    at test.Test.main(Test.java:10) 

不管我設置了多少超時時間。

這是我正在運行的代碼。我是socket編程新手請幫忙解決問題。

import java.io.*; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.InetAddress; 
import java.net.Socket; 

public class Test { 
    public static void main(String [] args) { 
     //tcp(); 
     udp(); 
    } 

    private static void tcp(){ 
     String serverName = "127.0.0.1"; 
     int port = 11211; 
     try { 
      System.out.println("Connecting to " + serverName + " on port " + port); 
      Socket client = new Socket(serverName, port); 

      System.out.println("Just connected to " + client.getRemoteSocketAddress()); 
      OutputStream outToServer = client.getOutputStream(); 
      DataOutputStream out = new DataOutputStream(outToServer); 

      out.writeBytes("stats\r\n"); 
      InputStream inFromServer = client.getInputStream(); 
      DataInputStream in = new DataInputStream(inFromServer); 

      System.out.println("Server says " + in.readLine()); 

      client.close(); 
     }catch(IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private static void udp(){ 
     DatagramSocket socket = null ; 

     try 
     { 
      InetAddress host = InetAddress.getByName("localhost") ; 
      socket = new DatagramSocket() ; 
      byte [] data = "stats\r\n".getBytes() ; 
      DatagramPacket packet = new DatagramPacket(data, data.length, host, 11211) ; 
      socket.send(packet) ; 
      socket.setSoTimeout(2000) ; 
      packet.setData(new byte[1024]) ; 
      socket.receive(packet) ; 
      System.out.println(new String(packet.getData())) ; 

     } 
     catch(Exception e) 
     { 
      System.out.println(e) ; 
     } 
     finally 
     { 
      if(socket != null) 
       socket.close() ; 
     } 
    } 

} 
+0

你可以嘗試捕獲Timeout異常並循環嘗試再次接收。 –

+0

@SteveSmith我在循環中嘗試了100次重試仍然沒有運氣。 – shubham12511

+0

服務器是否實際發送響應? –

回答

1

根據分佈式緩存的文檔(​​),而使用UDP協議發送數據,8字節的標題應在 相同的格式TCP協議發送隨後的數據。報頭結構如下:

  • 0-1請求ID
  • 2-3序號
  • 在這個消息
  • 6-7保留供將來使用的數據報的4-5總數;必須爲0

發送數據時添加標頭字節。就像這樣:

try 
    { 
     InetAddress host = InetAddress.getByName("localhost") ; 
     socket = new DatagramSocket() ; 

     byte [] data = "stats\r\n".getBytes() ; 
     ByteBuffer buffer = ByteBuffer.allocate(50); 
     buffer.putShort((short)0); 
     buffer.putShort((short) 0x0000;); 
     buffer.putShort((short) 0x0001;); 
     buffer.putShort((short) 0x0000;); 
     buffer.put(data); 
     DatagramPacket packet = new DatagramPacket(buffer.array(), buffer.array().length, host, 11211) ; 
     socket.send(packet) ; 
     socket.setSoTimeout(2000) ; 
     packet.setData(new byte[1024]) ; 
     socket.receive(packet) ; 
     System.out.println(new String(packet.getData())) ; 

    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
    finally 
    { 
     if(socket != null) 
      socket.close() ; 
    } 
+0

是的,它現在正在工作。這是一個很好的幫助。感謝名單! – shubham12511