Memcached 的 Java UDP 套接字客户端接收超时
Receive timed out in Java UDP socket client for Memcached
我有一个本地 Memcached 实例并尝试通过基本 Java TCP 和 UDP 套接字 API 访问它。 TCP 客户端工作正常,但 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)
无论我设置什么超时。
这是我的代码运行。我是套接字编程新手,请帮忙解决问题。
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() ;
}
}
}
根据 memcached 文档 (https://github.com/memcached/memcached/blob/master/doc/protocol.txt) ,在使用 udp 协议发送数据时,应发送 8 字节 header 后跟数据
与 TCP 协议格式相同。 header结构如下:
- 0-1 请求 ID
- 2-3序号
- 4-5 此消息中的数据报总数
- 6-7 留作以后使用;必须是 0
发送数据时增加header字节。像这样:
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() ;
}
我有一个本地 Memcached 实例并尝试通过基本 Java TCP 和 UDP 套接字 API 访问它。 TCP 客户端工作正常,但 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)
无论我设置什么超时。
这是我的代码运行。我是套接字编程新手,请帮忙解决问题。
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() ;
}
}
}
根据 memcached 文档 (https://github.com/memcached/memcached/blob/master/doc/protocol.txt) ,在使用 udp 协议发送数据时,应发送 8 字节 header 后跟数据 与 TCP 协议格式相同。 header结构如下:
- 0-1 请求 ID
- 2-3序号
- 4-5 此消息中的数据报总数
- 6-7 留作以后使用;必须是 0
发送数据时增加header字节。像这样:
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() ;
}