2017-06-01 119 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