在Memcached的Java UDP套接字客户端中接收超时
问题描述:
我有一个本地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() ;
}
}
}
答
根据分布式缓存的文档(),而使用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
你可以尝试捕获Timeout异常并循环尝试再次接收。 –
@SteveSmith我在循环中尝试了100次重试仍然没有运气。 – shubham12511
服务器是否实际发送响应? –