TCP套接字交换kryo序列化对象

时间:2014-10-15 15:22:53

标签: java sockets kryo

我目前正在开发一个通过TCP套接字发送/接收对象的项目。我选择使用Kryo Serialization框架,因为它是最受欢迎的框架之一。我看到网络通信,建议使用KryoNet,但出于我自己的原因,我选择使用自己的TCP Socket框架(主要是因为我想在我的项目中自定义控制TCP流和线程)。我遇到的问题是我为Messages创建了以下类:

public class MyMessage {

    public HashMap<String, String> _values;

    public MyMessage() {
        _values = new HashMap<String, String>();
    }
}

在服务器端,我有以下代码用于从TCP套接字读取输入:

import java.io.*;
import java.net.*;

public class MyServer {

    private ServerSocket _serverSocket;

    private Integer _serverPort;

    private boolean _killCommand;

    public MyServer() {
        _serverSocket = null;
        _serverPort = -1;
        try {
            _serverSocket = new ServerSocket(0);
            _serverPort = _serverSocket.getLocalPort();
            System.out.println("server started on IP: " + _serverSocket.getInetAddress().getHostAddress() + ":" + _serverPort);
        } catch (IOException e) {
            e.printStackTrace();
        }
        _killCommand = false;
    }

    public void runServer() {
        Socket _client= null;
        while(_killCommand == false) {
            try {
                _client = _serverSocket.accept();
                _out = _client.getOutputStream();
                _in = _client.getInputStream();
                (new Thread(new ServerThread(_in, _out))).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

ServerThread类:

import java.io.*;
import java.util.HashMap;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.*;

public class ServerThread implements Runnable {

    private InputStream _in;

    private OutputStream _out;

    private Kryo kryo;

    private Input _input;

    private Output _output;

    public SynEFOthread(InputStream in, OutputStream out) {
        _in = in;
        _out = out;
        kryo = new Kryo();
        _output = new Output(_out);
        _input = new Input(_in);
    }

    @Override
    public void run() {
        MyMessage msg = null;
        System.out.println("Thread worker: about to parse input message");
        msg = kryo.readObject(_input, MyMessage.class);
        }
    }
}

另一方面,客户端代码如下:

import java.io.*;
import java.net.Socket;
import java.util.*;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.*;

public class MyClient {

    public static void main(String[] args) throws Exception {
        String server_ip = "";
        Integer server_port = -1;

        server_ip = args[0];
        server_port = Integer.parseInt(args[1]);

        Socket serverSocket = new Socket(server_ip, server_port);
        OutputStream _out = serverSocket.getOutputStream();
        InputStream _in = serverSocket.getInputStream();
        Output _output = new Output(_out);
        Input _input = new Input(_in);
        MyMessage msg = new MyMessage();
        msg._values = new HashMap<String, String>();
        msg._values.put("TASK_TYPE", "TOPOLOGY");
        Kryo kryo = new Kryo();
        kryo.writeObject(_output, msg);
        Thread.sleep(100);
        kryo.writeObject(_output, _msg);
        String _ack = kryo.readObject(_input, String.class);
        serverSocket.close();
    }
}

问题是在ServerThread.run()函数上,kryo.readObject()调用阻塞,之后什么也没做。难道我做错了什么?我是否正确打开流以与Kryo序列化框架一起使用?

1 个答案:

答案 0 :(得分:0)

  1. 在客户端和服务器端使用kryo.register(MyMessage.class)注册您的课程。
  2. 为序列化/反序列化代码创建测试,但不使用套接字,而是使用ByteArrayOutputStream / ByteArrayInputStream。
  3. 冲洗!在将完整的消息写入流后,将写入的字节刷新到网络:_output.flush()