簡體   English   中英

C ++套接字-wstring到Java套接字

[英]C++ socket - wstring to Java socket

我有一台具有自定義協議的服務器(用於即時消息傳遞-該協議已在桌面客戶端上使用),目前正在嘗試在Android應用上實現它。

我已經設法打開服務器的套接字並發送一個4字節的整數,但是,我無法讓Java從服務器發送字符串或(正確地)接收字符串。

該服務器是用C ++編寫的,並托管在Windows計算機上,它使用wstring進行通信(以允許發送非ASCII字符)。 如何使應用以正確的格式讀取/寫入套接字? 我相信,在這種用法中,wstring應該是UTF-16字符串,但是我不確定字節序。

到目前為止,這是Java代碼(在測試時,我暫時禁用了NetworkOnMainThread異常):

private String recv_from_server() {
    String ret = "";
    char[] bytes = new char[8192];
    try {

        int in = sinput.read(bytes, 0, 8192);
        if(in > 0) {
            byte[] str = bytes.toString().getBytes("UTF-8");
            ret = new String(str, "UTF-8");
        }
    }
    catch(Exception ex) {}
    return ret;
}


private void send_to_server(String message) {
    try {
        soutput.write(message);
        soutput.flush();
    }
    catch(Exception ex) {
        ((TextView)findViewById(R.id.chat_message_message)).setText(ex.toString());
    }
}

@Override
protected void onStart() {
    super.onStart();
    refresh();
    refresher = new Timer();
    refresher.schedule(new RefresherEvt(), 15000);
    if(open_connection() == true) {
        String ret = "";
        while(ret == "") {
            ret = recv_from_server();
        }
        ((TextView)findViewById(R.id.chat_message_message)).setText(ret);
        send_to_server("test message");
    }
}

我從recv_from_server函數獲取垃圾數據,而send函數似乎從未到達服務器。

提前致謝。

這段代碼:

byte[] str = bytes.toString().getBytes("UTF-8");
ret = new String(str, "UTF-8");

只會返回"[B@nnnnnn"形式的字符串,因為char[]不會覆蓋Object.toString(). 雙重轉換也無法完成任何有用的操作。 當然, char[]數組應該稱為chars ,而不是bytes 它應該是:

return new String(chars, 0, in, "UTF-8"); // or UTF-16 or whatever you determine

我假設sinput是圍繞輸入流的BufferedReader 否則,您的代碼將無法編譯。

第一:此變量的名稱肯定令人困惑

char[] bytes = new char[8192];

它和char數組(稱為字節)在JAVA下絕對不是一回事。

第二:我不知道您在這里使用哪種流。 有些可以直接讀取char,有些可以內部從UTF-8轉換為UTF-16等...等等。

int in = sinput.read(bytes, 0, 8192);  

但是第三:據我所知,這沒有任何作用:

byte[] str = bytes.toString().getBytes("UTF-8");
ret = new String(str, "UTF-8");

您假定您有一個有效的String(以bytes (實際上是char),並將其轉換為UTF-8編碼的字節數組(稱為str)。 然后,將其從UTF-8轉換回ret的JAVA內部UTF-16編碼。 為什么不只返回bytes.toString()呢?

一種可能性

您說C代碼中的字符串也就是wstring。 基於UTF-16或UCS2。 據我所知Windows版本。 因此,一種假設是,您接收到的數據是UTF-16編碼的,並且如果它實際上是UCS2,您仍將覆蓋BMP中的所有字符。 因此,我要嘗試的第一件事是直接從UTF-16對其進行解碼,例如:

byte[] bytes = new byte[BUFFERSIZE];
// Actually read bytes -- don't know
// if your stream can handle that
int n sinput.read(bytes,0,BUFFERSIZE);
// silently assume n % 2 == 0 and UTF-16 doesn't use surrogates
String str = new String(bytes,n,"UTF16-BE" /*"UTF16-LE"*/);

然而

大多數情況下,std :: wstring格式僅用於內部字符串表示,因為對於大多數字符而言,一個字符具有一個字符串位置。 您不必使用可變長度編碼。 對於UCS4完全適用,對於UTF-16幾乎適用。 這使其在內部具有很大的優勢。 但是又是外部代表。 文件或Internet UTF-8是通用語言,因為它結構緊湊,不關心字節序,並且ASCII仍可作為ASCII看到,沒有任何零散的零字節..等等。

因此,即使沒有看到C代碼,我仍然會假設外部表示形式很有可能成為UTF-8。 在這種情況下,您只需要做:

byte[] bytes = new byte[BUFFERSIZE];
// Actually read bytes -- don't know
// if your stream can handle that
sinput.read(bytes,0,BUFFERSIZE);
String str = new String(bytes,BUFFERSIZE,"UTF8");

對於您的soutput.write(...),您還必須調用getBytes(“ UTF8”)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM