2014-06-17 2 views
0

현재 C 및 Java로 작성된 응용 프로그램의 통신과 관련된 프로젝트를 진행 중입니다. 따라서 Apache Avro와 협력하기로했습니다. Avro가 DataFileWriter 클래스를 사용하여 파일에서 객체를 직렬화 할 수 있다는 것을 웹 사이트에서 보았습니다.TCP 소켓을 통한 Avro 통신

내 경우에는 응용 프로그램간에 TCP 소켓을 사용하고 싶습니다. 따라서 DataFileWriter 클래스는 나를 위해 작동하지 않습니다. 문서를 읽은 후에 TCP 소켓을 통해 객체를 보내는 방법에 대한 정보를 찾지 못했습니다.

그 방법에 대한 아이디어가 있으십니까? 필자는 Java 클라이언트에서 사용해야하는 입력 및 출력 스트림의 종류를 알고 싶습니다.

나는 자바 서버에 대한 다음 코드를 개발했다 :

import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.OutputStream; 
import java.io.PrintWriter; 
import java.net.Socket; 

import middleman.bigpeer.BigPeer; 

import org.apache.avro.io.BinaryDecoder; 
import org.apache.avro.io.BinaryEncoder; 
import org.apache.avro.io.DecoderFactory; 
import org.apache.avro.io.EncoderFactory; 
import org.apache.avro.specific.SpecificDatumReader; 
import org.apache.avro.specific.SpecificDatumWriter; 

public class SystemClient { 

    public static void connect(String serverIPAddress, Integer serverPort) throws IOException, ClassNotFoundException { 
     /** 
     * Create Connection with the server 
     */ 
     Socket socket = new Socket(serverIPAddress, serverPort); 
     InputStream in = socket.getInputStream(); 
     OutputStream out = socket.getOutputStream(); 
     EncoderFactory encoderFactory = new EncoderFactory(); 
     DecoderFactory decoderFactory = new DecoderFactory(); 
     BinaryEncoder binaryEncoder = encoderFactory.binaryEncoder(out, null); 
     BinaryDecoder binaryDecoder = decoderFactory.binaryDecoder(in, null); 

     BigPeer bigPeer = new BigPeer(); 
     bigPeer.setType("test"); 
     SpecificDatumReader<BigPeer> reader = new SpecificDatumReader<BigPeer>(BigPeer.class); 
     SpecificDatumWriter<BigPeer> writer = new SpecificDatumWriter<BigPeer>(BigPeer.class); 

     System.out.println("Before: " + bigPeer.getType()); 
     writer.write(bigPeer, binaryEncoder); 
     System.out.println("Waiting for response..."); 
     reader.read(bigPeer, binaryDecoder); 
     System.out.println("After: " + bigPeer.getType()); 
    } 

} 

그리고 서버는 코드의 peerDatumReader.read(bigPeer, binaryDecoder); 라인에 정지 할 것 같다 :

import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.net.Socket; 
import java.util.HashMap; 

import middleman.bigpeer.BigPeer; 

import org.apache.avro.generic.GenericDatumWriter; 
import org.apache.avro.io.BinaryDecoder; 
import org.apache.avro.io.BinaryEncoder; 
import org.apache.avro.io.DatumReader; 
import org.apache.avro.io.DecoderFactory; 
import org.apache.avro.io.EncoderFactory; 
import org.apache.avro.specific.SpecificDatumReader; 
import org.apache.avro.specific.SpecificDatumWriter; 

public class MiddleManWorker implements Runnable { 

    private InputStream in; 

    private OutputStream out; 

    private Socket clientSocket; 

    public MiddleManWorker(Socket clientSocket, HashMap<Integer, NodeType> dbNodesDirectory, 
      HashMap<Integer, NodeType> workersDirectory) { 
     this.clientSocket = clientSocket; 
     try { 
      this.in = clientSocket.getInputStream(); 
      this.out = clientSocket.getOutputStream(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void run() { 
     EncoderFactory encoderFactory = new EncoderFactory(); 
     DecoderFactory decoderFactory = new DecoderFactory(); 
    BinaryEncoder binaryEncoder = encoderFactory.binaryEncoder(out, null); 
     BinaryDecoder binaryDecoder = decoderFactory.binaryDecoder(in, null); 
     SpecificDatumReader<BigPeer> peerDatumReader = new SpecificDatumReader<BigPeer>(BigPeer.class); 
     BigPeer bigPeer = null; 
     SpecificDatumWriter<BigPeer> writer = new SpecificDatumWriter<BigPeer>(); 
     try { 
      peerDatumReader.read(bigPeer, binaryDecoder); 
      System.out.println("Received: " + bigPeer.getType()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     try { 
      writer.write(bigPeer, binaryEncoder); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 


    } 

} 

샘플 자바 클라이언트는 다음과 같습니다. 어떤 아이디어?

답변

1

BinaryEncoder는 성능상의 이유로 내부 버퍼를 사용 닉을 주셔서 감사합니다. 파이프를 통해 데이터를 보내려면 인코더에서 flush를 호출해야 할 수도 있습니다.

이 문제에 대한 자세한 내용은 reference를 참조하십시오

BinaryEncoder 구현의 출력을 버퍼링 할 수 돌아왔다. Flushable.flush()가 호출 될 때까지 데이터가 기본 OutputStream에 표시되지 않을 수 있습니다. 버퍼 사이즈는 configureBufferSize (int)로 설정됩니다. 버퍼링 요구 및 낮은 성능이 허용되지 않으면

,

directBinaryEncoder (OutputStream에, BinaryEncoder)를 사용
관련 문제