0

まず、NetBeans IDE を使用しています。1 つのスレッドがサーバーからメッセージを受信して​​ベクターに入れ、別のスレッドがそれらを処理するクライアントがあります。MessageListener と MessageHandler がそれです。したがって、問題は、受信した最初のメッセージは正常に機能していることですが、次のメッセージで byte[] getFirstMessage() メソッドを呼び出すと、値が 0 の byte が返されます。

私の意見では、問題は、2番目のメッセージを0ではなくインデックス1に追加するVector addElementメソッドにありますが、そのデータをMessageHandlerに渡すとすぐにベクトルの最初の要素の内容を削除するか、使用します一部のメソッドのローカル変数。PSそれはメッセージキューだったはずです。

MessageListener.java

package org.rebirth;

import java.io.*;
import java.util.*;

public class MessageListener implements Runnable{

Vector v; 
int size = 0;
Connections con;
byte[] buffer = new byte[100000];
boolean noErrors = true;

public MessageListener(Connections con){
    v = new Vector(50,10);

    this.con = con;

    Thread thr = new Thread(this);
    thr.start();
}

public void run(){

    while(noErrors){            
        try{   

            listenForData();
            Thread.sleep(1);            
        }catch(Exception exc){
            exc.printStackTrace();  
            noErrors = false;
        }
    }
}

public void listenForData() throws IOException{


    con.fill(buffer,(byte)0);
    System.out.println("Trying to receive data");
    // InputStream                                                             
    con.in.read(buffer);
    System.out.println("Data received id "+con.ReadInt3Bytes(buffer,1));
    v.addElement(buffer);
    size++;

    if(v.isEmpty()){
        System.out.println("empty");
    }


}

public byte[] getFirstMessage(){
    if(v.size()>0){
        byte[] data = (byte[]) v.firstElement();
        v.removeElementAt(0); 
        size--;

        System.out.println("first byte element "+(int)data[0]);

        return data;
    }
    return null;
}

}

Messagehandler.java

 package org.rebirth;

 import java.util.*;
 import javax.microedition.lcdui.game.*;

public class MessageHandler implements Runnable{

Vector v;
MessageListener lst;
Connections con;
int vienas = 1;

public MessageHandler(Vector v,MessageListener lst){
    this.v = v;
    this.lst = lst;
    this.con = lst.con;

    Thread thr = new Thread(this);
    thr.start();
}


public void run(){
    while(true){
        try{

            if(!v.isEmpty()){                    
                handleMessages();

            }
            Thread.sleep(10);            
        }catch(Exception exc){}
    }
}

public void handleMessages(){
   // vectordsfds

    int id;

    byte [] gotByte = lst.getFirstMessage();        
    id=con.ReadInt3Bytes(gotByte,1);       
    System.out.println("handler id: "+id);

    // call a method to handle received message;
    handleMessage(id,gotByte);          
}

public void handleMessage(int id,byte[] gotByte){
    switch(id){            

        case 62:
            // GameServerList

            con.serverNumber = (int)gotByte[4];
            System.out.println("Servers "+con.serverNumber);        

                    int nri = 6;
                    for(int i=0;i<con.serverNumber;i++){

                        nameLength = (int)gotByte[nri];
                        nri+=1;
                        con.serverName[i] = new String(gotByte, nri, nameLength);
                        nri+=nameLength;
                        int ipLength = (int)gotByte[nri];
                        nri+=1;
                        con.serverIp[i] = new String(gotByte, nri, ipLength);
                        nri+=ipLength;
                        con.online[i] = con.ReadInt3Bytes(gotByte,nri);
                        nri+=3;
                        con.maxOnline[i] = con.ReadInt3Bytes(gotByte,nri);

                        System.out.println("Server name " +con.serverName[i]);
                        System.out.println("ip "+con.serverIp[i]);
                        System.out.println("online "+con.online[i]);
                        System.out.println("max online "+con.maxOnline[i]);
                        nri+=4;
                    }

            break;

        case 64:
            //GameVersion


            int success = (int)gotByte[4];


            if(success == 1){
                con.version=true;
                System.out.println("Version match!");

        }else{
                System.out.println("version does not match");
                System.out.println(success);
            }

        break;




    }
}


}

編集 2: データを読み取る前に、ステートメント InputStream クラス available() メソッドを追加しました。

4

2 に答える 2

0

私はそれが時々働くことに驚いています。ソースを正しく読んでいる場合、すべての着信メッセージに対して同じバッファー インスタンスを使用しています。Vector.addElement はバッファのコピーを作成せず、param として渡された参照を保存するだけなので、while(noErrors) ループで実行されている listenForData は、再実行されるとすぐに (唯一の) バッファをゼロでクリアします。そして、スレッドがどのようにスケジュールされているかによって再度実行されると、メッセージリスナーは実際のデータでバッファを取得する場合とゼロでバッファを取得する場合があります。

また、J2SE とは異なり、CLDC Vector が同期されているかどうかもわかりません。したがって、ベクトルアクセスは同期する必要があると思います。また、使用している接続の種類もわかりませんが、戻り値をチェックせずに、読み取るバイト数を知らずにストリームからバイトを読み取ることは、少し信頼できないコードのように思えます...

編集:「読み取る必要があるバイト数を知る」ということは、多くの種類のストリームに対して 0 を返す可能性が高い available() 関数を使用することを意味するものではありませんでした。read() が返されると、要求されたよりも少ないバイト数を読み取る可能性があります (実際にそうなることがよくあります)。そのため、待機しているデータの量を把握して読み取りを続けない限り、バッファに十分なデータがあるかどうかを確認することはできません。あなたがそれらを手に入れるまで。プロトコルを定義する必要があると思います。必要に応じて、固定サイズのメッセージと同じくらい単純にすることができます。

于 2013-08-15T09:32:29.460 に答える
0

コードで何が起こるかを正確に理解することはそれほど簡単ではありません。ただし、メソッドlistenForData()は実際にゼロで埋められたバイト配列をベクトルに追加します。

con.fill(buffer,(byte)0); 
......
v.addElement(buffer);

ですから、あなたはここに来たばかりですが、私はあなたを歓迎し、あなたの成功を祈りたいと思います.いくつか質問したいと思います.

  1. J2ME が時代遅れであることを知っていますか? モバイルデバイスからプログラミングしたい場合は、Android OS を見てください。
  2. VectorJDK クラス ( など) には、最初のプログラムを作成することで発見できるバグが含まれていると本当に思いますか?
  3. デバッガーについて聞いたことがありますか? コードが機能しない理由を理解するために、コードをデバッグしてみてください。
  4. 質問して適切な回答を得たい場合は、SSCCEをご覧ください。

幸運を。

于 2013-08-13T05:53:24.893 に答える