1

JavaとC++の通信で使用するクラスを作成したい

JavaとC++の通信については多くの議論があります。ここで私はコミュニケーションの方法を要求していません、私は私が方法を知っていると思います。

私は作成します

 OutputStream os = socketChannel.socket().getOutputStream();
 OutputStreamWriter osw = new OutputStreamWriter( os);
 BufferedWriter wr = new BufferedWriter( osw );

それから私は書く

 String data= dataArea.getText();

 wr.write( dataArea.getText() );
 wr.write('\0');//here is the wire with C++
 wr.flush(); // flushes the stream

私はいくつかのテキストを送ります:

Hi this is a test
i send also 
character as dollar $ ...
or other stange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*
and so on

したがって、生のテキストを読むと、2つのシステム間で送信されます。

00000000  48 69 20 74 68 69 73 20  69 73 20 61 20 74 65 73   Hi this  is a tes 
00000010  74 0A 69 20 73 65 6E 64  20 61 6C 73 6F 20 0A 63   t.i send  also .c 
00000020  68 61 72 61 63 74 65 72  20 61 73 20 64 6F 6C 6C   haracter  as doll 
00000030  61 72 20 24 20 2E 2E 2E  0A 6F 72 20 6F 74 68 65   ar $ ... .or othe 
00000040  72 20 73 74 61 6E 67 65  20 C3 A9 2A 22 C2 A3 24   r stange  ..*"..$ 
00000050  25 26 2F 28 28 29 3D 3F  27 5E C3 AC C3 AC 5B 5D   %&/(()=? '^....[] 
00000060  40 21 3C 3E 23 C3 B2 C3  B9 C3 A8 C3 A9 2B 2A 0A   @!<>#... .....+*. 
00000070  61 6E 64 20 73 6F 20 6F  6E 00                     and so o n.

これは解決策に近いです。

取得したCHARSET「US-ASCII」の変更

Hi this is a test
    i send also 
    character as dollar $ ...
    or other stange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*
    and so on


00000000  48 69 20 74 68 69 73 20  69 73 20 61 20 74 65 73   Hi this  is a tes 
00000010  74 0A 20 20 20 20 69 20  73 65 6E 64 20 61 6C 73   t.    i  send als 
00000020  6F 20 0A 20 20 20 20 63  68 61 72 61 63 74 65 72   o .    c haracter 
00000030  20 61 73 20 64 6F 6C 6C  61 72 20 24 20 2E 2E 2E    as doll ar $ ... 
00000040  0A 20 20 20 20 6F 72 20  6F 74 68 65 72 20 73 74   .    or  other st 
00000050  61 6E 67 65 20 3F 2A 22  3F 24 25 26 2F 28 28 29   ange ?*" ?$%&/(() 
00000060  3D 3F 27 5E 3F 3F 5B 5D  40 21 3C 3E 23 3F 3F 3F   =?'^??[] @!<>#??? 
00000070  3F 2B 2A 0A 20 20 20 20  61 6E 64 20 73 6F 20 6F   ?+*.     and so o 
00000080  6E 00 

これは私の目的に近いです。


拡張文字「è」->E8を含むASCIIのみを転送する必要があります

次に、文字列の最後に「\0」を付ける必要があります。

'\0'はメッセージターミネータです。

ここで質問:Javaを使用して、特定のバイナリデータ形式を出力するライターまたはストリームライターを作成するのが好きです。

どのレベルで作業するのが正しいですか、OutputStreamWriterまたはBufferedWriter最初から書き直して拡張するか、ライブラリを使用する必要がありますか?私がやりたいことについての例はありますか? 入力についても同じことをします

明日JavaでC++サーバーを書き直すときに、両側のDataOutputStreamを使用するため、この形式で記述するのが好きです。

を使用することwhileは良い解決策ではありません。私はよりJava統合された解決策を好みます。

4

2 に答える 2

1

このストリームは、必要に応じて自動フラッシュが有効で、US-ASCIIです。

OutputStream os = socketChannel.socket().getOutputStream();
PrintStream ps = new PrintStream( os, true, "US-ASCII" );
ps.print( "tange é*"£$%&/(()=?'^ìì[]@!<>#òùèé+*" );
os.write( (byte)0 ); // end-of-message
于 2013-02-14T17:39:42.470 に答える
1

BufferedWriterとBufferedReaderに基づいて可能な解決策を実行しました。正しいASCII拡張文字エンコードであるISO-8859-1を使用しました。


OutputStream os = socketChannel.socket().getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os, "ISO-8859-1");
TBufferedWriter bw = new TBufferedWriter (osw);
bw.writeTMessageFlushing( dataArea.getText() );


InputStream is = socketChannel.socket().getInputStream();
InputStreamReader isr= new InputStreamReader(is, "ISO-8859-1") ;
TBufferedReader br= new TBufferedReader(isr);
// wait for response
String responseLine = br.readTMessage();

BufferedWriterとBufferedReaderのソースを開いて、インタラクションを取得する方法を調べました。

BufferedReaderは、いくつかの関数を使用しているため、単純に拡張することはできません(java Boysから書き直す必要があります)。バッファリーダーを拡張しますが、役に立たない


import java.io.BufferedWriter;
import java.io.IOException;
import java.io.Writer;


public class TBufferedWriter extends BufferedWriter {


    public TBufferedWriter(Writer out){
        super( out );
    }
    public TBufferedWriter(Writer out, int sz){
        super( out, sz );
    }

    public void writeTMessage(String message) throws IOException {
         synchronized (lock) {
              super.write( message );
              super.write('\0');
         }
    }
     public void writeTMessageFlushing(String message) throws IOException {
         synchronized (lock) {
              super.write( message );
              super.write('\0');
              super.flush();
         }
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;


public class TBufferedReader extends BufferedReader {
    private Reader in;
    private char cb[];
    private int nChars, nextChar;
    private static final int INVALIDATED = -2;
    private static final int UNMARKED = -1;
    private int markedChar = UNMARKED;
    private int readAheadLimit = 0; /* Valid only when markedChar > 0 */

    /** If the next character is a line feed, skip it */
    private boolean skipNUL = false;
    /** The skipLF flag when the mark was set */
    private boolean markedSkipLF = false;
    private static int defaultCharBufferSize = 8192;
    private static int defaultExpectedLineLength = 80;


    /**
     * Creates a buffering character-input stream that uses an input buffer of
     * the specified size.
     *
     * @param  in   A Reader
     * @param  sz   Input-buffer size
     *
     * @exception  IllegalArgumentException  If sz is <= 0
     */
    public TBufferedReader( Reader in, int sz ) {
        super( in );
        if (sz <= 0) {
            throw new IllegalArgumentException( "Buffer size <= 0" );
        }
        this.in = in;
        cb = new char[ sz ];
        nextChar = nChars = 0;
    }


    /**
     * Creates a buffering character-input stream that uses a default-sized
     * input buffer.
     *
     * @param  in   A Reader
     */
    public TBufferedReader( Reader in ) {
        this( in, defaultCharBufferSize );
    }


    /** Checks to make sure that the stream has not been closed */
    private void ensureOpen() throws IOException {
        if (in == null) {
            throw new IOException( "Stream closed" );
        }
    }


    /**
     * Fills the input buffer, taking the mark into account if it is valid.
     */
    private void fill() throws IOException {
        int dst;
        if (markedChar <= UNMARKED) {
            /* No mark */
            dst = 0;
        } else {
            /* Marked */
            int delta = nextChar - markedChar;
            if (delta >= readAheadLimit) {
                /* Gone past read-ahead limit: Invalidate mark */
                markedChar = INVALIDATED;
                readAheadLimit = 0;
                dst = 0;
            } else {
                if (readAheadLimit <= cb.length) {
                    /* Shuffle in the current buffer */
                    System.arraycopy( cb, markedChar, cb, 0, delta );
                    markedChar = 0;
                    dst = delta;
                } else {
                    /* Reallocate buffer to accommodate read-ahead limit */
                    char ncb[] = new char[ readAheadLimit ];
                    System.arraycopy( cb, markedChar, ncb, 0, delta );
                    cb = ncb;
                    markedChar = 0;
                    dst = delta;
                }
                nextChar = nChars = delta;
            }
        }

        int n;
        do {
            n = in.read( cb, dst, cb.length - dst );
        } while (n == 0);
        if (n > 0) {
            nChars = dst + n;
            nextChar = dst;
        }
    }


    /**
     * Reads a line of text.  A line is considered to be terminated by any one
     * of a line feed ('\0')
     *
     * @param      ignoreNUL  If true, the next '\0' will be skipped
     *
     * @return     A String containing the contents of the line, not including
     *             any line-termination characters, or null if the end of the
     *             stream has been reached
     *
     * @see        java.io.LineNumberReader#readLine()
     *
     * @exception  IOException  If an I/O error occurs
     */
    String readTMessage( boolean ignoreNUL ) throws IOException {
        StringBuffer s = null;
        int startChar;

        synchronized (lock) {
            ensureOpen();
            boolean omitNUL = ignoreNUL || skipNUL;
bufferLoop:     for (;;) {
                    if (nextChar >= nChars) {
                        fill();
                    }
                    if (nextChar >= nChars) { /* EOF */
                        if (s != null && s.length() > 0) {
                            return s.toString();
                        } else {
                            return null;
                        }
                    }
                    boolean eol = false;
                    char c = 0;
                    int i;

                    /* Skip a leftover '\0', if necessary */
                    if (omitNUL && (cb[nextChar] == '\0')) {
                        nextChar++;
                    }
                    skipNUL = false;
                    omitNUL = false;

charLoop:               for (i = nextChar; i < nChars; i++) {
                            c = cb[i];
                            if ((c == '\0')) {
                                eol = true;
                                break charLoop;
                            }
                        }

                    startChar = nextChar;
                    nextChar = i;

                    if (eol) {
                        String str;
                        if (s == null) {
                            str = new String( cb, startChar, i - startChar );
                        } else {
                            s.append( cb, startChar, i - startChar );
                            str = s.toString();
                        }
                        nextChar++;
                        if (c == '\0') {
                            skipNUL = true;
                        }
                        return str;
                    }

                    if (s == null) {
                        s = new StringBuffer( defaultExpectedLineLength );
                    }
                    s.append( cb, startChar, i - startChar );
                }
        }
    }


    /**
     * Reads a line of text.  A line is considered to be terminated by any one
     * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
     * followed immediately by a linefeed.
     *
     * @return     A String containing the contents of the line, not including
     *             any line-termination characters, or null if the end of the
     *             stream has been reached
     *
     * @exception  IOException  If an I/O error occurs
     *
     * @see java.nio.file.Files#readAllLines
     */
    public String readTMessage() throws IOException {
        return readTMessage( false );
    }
}

他の興味深いクラスは

http://www.ibm.com/developerworks/java/zos/javadoc/jzos/index.html?com/ibm/jzos/TranscodingPrintStream.html

org.apache.james.util.CharTerminatedInputStream


CharTerminatedInputStreamに関するニュースを追加します。使用中の正しい文字セットを管理する必要があるため、thtatクラスの使用は危険です。outputStreamはより高レベルであり、InputStreamReaderを挿入できます。

于 2013-02-15T14:33:22.597 に答える