0

我正在尝试在 Unity3D 应用程序和 Java (Jason) 应用程序之间建立套接字网络(在 Java 部分使用“BufferedOutputStream”,在 C# 部分使用“NetworkStream”)。这两个模块应该相互通信。这是代码的java部分:

public static void SendExecuteAction(String ag, Structure structure, Object tempObject, ClassEnv classEnv)
    {   
        if(!agentThreadList.containsKey(ag))
        {
            AgentServiceThread ast = new AgentServiceThread(s, agentThreadList.size() - 1, ag, structure, tempObject, classEnv);
            agentThreadList.put(ag, ast);
            if(ast.getState() != Thread.State.BLOCKED)
                ast.start();
            try {
                ast.join();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else
        {
            agentThreadList.get(ag).start();
        }
    }
}

class AgentServiceThread extends Thread
{
    Socket agentSocket;
    int agentID = -1;
    String agent;
    Structure structure;
    Object blockObject;
    byte[] ba;
    ClassEnv classEnv;

    InputStream is;
    BufferedOutputStream bos;
    ToByteConvertHelper toBytes;
    FromByteConvertHelper fromBytes;


    AgentServiceThread(Socket s, int i, String ag, Structure structure, Object object, ClassEnv classEnv)
    {
        agentSocket = s;
        agentID = i;
        agent = ag;
        this.structure = structure;
        blockObject = object;
        this.classEnv = classEnv;

        try 
        {
            toBytes = new ToByteConvertHelper();
            fromBytes = new FromByteConvertHelper();
            is = agentSocket.getInputStream();
            bos = new BufferedOutputStream(agentSocket.getOutputStream());
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    public void run()
    {
        VCActionRequest vcar;

        List<String> termList = new ArrayList<String>();

        List<Term> structureTermList = structure.getTerms();

        for(int i = 0; i < structureTermList.size(); i++)
        {
            termList.add(structureTermList.get(i).toString());
        }

        vcar = new VCActionRequest(agent, structure.getFunctor(), (ArrayList<String>)termList);
        vcar.requestEnum = RequestEnum.ExecuteActions.index();

        System.out.println("agent: " + agent + " action: " + structure.getFunctor());

        ba = toBytes.toByte(vcar);

        try 
        {
            bos.write(ba);
            bos.flush();
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }

        synchronized(blockObject)
        {
            try 
            {
                ba = new byte[1000];
                is.read(ba, 0, 1000);

                @SuppressWarnings("unchecked")
                ArrayList<VCPerception> result = (ArrayList<VCPerception>)fromBytes.fromByte(ba);

                classEnv.UpdatePercepts(result);
            } 
            catch (IOException e1) 
            {
                System.out.println(e1.toString());
                e1.printStackTrace();
            } 
        }


    }   
}

“SendExecuteAction”方法被另一个方法调用,该方法由 Jason 架构在其间隔内自动调用。问题是,当我尝试从 Unity3D 应用程序中获取包时,似乎我错过了一些包。实际上,我从 Unity 获得了第一个包,但没有其他包。我应该使用某种不同的交流方式吗?我需要异步阅读每条消息。这是用于从网络流中读取数据的 C# 代码。

    private IEnumerator CommunicateWithMAS()
    {

        while (!_ns.DataAvailable)
        {
            yield return null;
        }

        byte[] ba = new byte[1000];

        AgentServiceThread ast = new AgentServiceThread(_tc, -1, this, ba);
        Thread thread = new Thread(new ThreadStart(ast.Communicate));

        thread.Start();

        StartCoroutine(CommunicateWithMAS());
    }


public class AgentServiceThread
{
    VCSocketCommScript socketCommScript;
    TcpClient client;
    int id;
    string agentName;

    NetworkStream ns;
    StreamWriter sw;
    StreamReader sr;
    string informationString;
    string responseString;
    FromByteConvertHelper fromBytes;
    byte[] ba;

    int byteArrayLength = 1000;

    public AgentServiceThread(TcpClient client, int id, VCSocketCommScript vcscs, byte[] ba)
    {
        this.client = client;
        this.id = id;
        socketCommScript = vcscs;
        //this.ba = ba;

        fromBytes = new FromByteConvertHelper();

        ns = client.GetStream();
    }

    public void Communicate()
    {
        byte[] ba = new byte[byteArrayLength];

        Debug.Log(ns.DataAvailable);
        ns.Read(ba, 0, byteArrayLength);

        //Debug.Log(ba.Length);

        VCActionRequest action = (VCActionRequest)fromBytes.fromByte(ba, 0, typeof(VCActionRequest));

        Debug.Log(action.agentName + " " + action.functor);

        socketCommScript.AddAction(action);

        ns.Flush();
    }
}
4

0 回答 0