TCP многопоточность - PullRequest
       31

TCP многопоточность

0 голосов
/ 28 ноября 2018

Пожалуйста, посмотрите на мой нубийский код ниже.Намерение состоит в том, чтобы создать сервер, к которому несколько клиентов могут присоединяться и отправлять данные постоянно.

Работает до 3 клиентов без ошибок, как только четвертый клиент присоединяется, в то время как три других начали передавать данные черезсервер зависает.

У меня нет журнала или чего-либо еще, поскольку планшет полностью завис.Необходимо принудительно закрыть приложение.

Я полагаю, оно вызвано одним из (истинных) супер-решений, которое я получил, но не могу понять, почему это не происходит раньше, до того, как четвертый клиент присоединяется.

SERVER:

public class TCPServer extends Thread implements Serializable {


Message receivedMessage = new Message();
ServerSocket serverSocket;
Socket socket;
ObjectInputStream ois;

public static ArrayList<Socket> ClientList = new ArrayList<>();

public void run() {
    try {

        serverSocket = new ServerSocket(6000);

        while(true)
        {
            socket = serverSocket.accept();
            ClientList.add(socket);
            ois = new ObjectInputStream(socket.getInputStream());

            Thread t = new Thread(new TCPComThread(socket,ois));
            t.start();
        }

    }catch (IOException ioe){
        try{
          socket.close();
        }catch(Exception e)
        {e.printStackTrace();
            ioe.printStackTrace();}

    }

}

И TCPCOMTHREAD:

   class TCPComThread implements Runnable{
   private Socket client;
   private ObjectInputStream oisFromOutside;

   TCPComThread(Socket client, ObjectInputStream oisFromOutside)
   {
        this.client = client;
        this.oisFromOutside = oisFromOutside;
   }

    public void run(){

        MessageToServer obj_message_to_server;
        LessonToServer obj_lesson_to_server;

        try {

            Object aux;

            while(!client.isClosed()) {

                aux = oisFromOutside.readObject();
                if (aux instanceof LessonToServer) {
                    obj_lesson_to_server = (LessonToServer) aux;

                    //receivedMessage.obtain();
                    receivedMessage = new Message();
                    receivedMessage.obj = obj_lesson_to_server;
                    LessonToServerHandler.sendMessage(receivedMessage);

                }

                if (aux instanceof MessageToServer) {
                    obj_message_to_server = (MessageToServer) aux;

                    //receivedMessage.obtain();
                    receivedMessage = new Message();
                    receivedMessage.obj = obj_message_to_server;
                    MessageToServerHandler.sendMessage(receivedMessage);
                }
            }
        }catch (Exception e)
        {
            e.printStackTrace();

        }

    }

}

Может кто-нибудь указать, что может быть причиной вышеуказанной проблемы?Спасибо

РЕДАКТИРОВАТЬ: Я считаю, что приведенный выше код в порядке, после комментирования все после readobject он не зависает.Так что проблема, вероятно, с обработчиком.HANDLER CODE:

private static Handler LessonToServerHandler = new Handler(){
    @Override
    public void handleMessage(Message msg){

        LessonToServer obj = (LessonToServer) msg.obj;

       // SAVE THE IMAGE TO INTERNAL STORAGE

        Log.e("SCHOOLID",obj.SchoolID);
        Log.e("CHILDID",obj.ChildID);
        Log.e("LESSONNAME",obj.Lessonname);
        Log.e("LESSONNUMBER",obj.Lessonnumber);
        Log.e("RESULT",obj.Result);
        Log.e("ISJUNK",obj.IsJunk.toString());

        Bitmap bitmap = Coding.decodeBase64(obj.byteArray);

        Shared.Utils.saveToInternalStorage(bitmap,obj.SchoolID,obj.ChildID,obj.Lessonname,obj.Lessonnumber,obj.Result, ServerApplication.getAppContext(),obj.IsJunk);

    }
};

1 Ответ

0 голосов
/ 11 декабря 2018

Это похоже на случай "потока пользовательского интерфейса, выполняющего слишком много работы" (основанного на количестве заданий "запись-файл", которые помещаются в очередь потока пользовательского интерфейса через sendMessage()).

Таккак это исправить?Возможно, пришло время переложить часть работы в поток, не связанный с пользовательским интерфейсом.К счастью, у вас уже есть несколько: ваш TCPComThreads.Основываясь на представленном коде, вам все равно не нужно делать запись файла в потоке пользовательского интерфейса.Вы можете просто заменить вызов LessonToServerHandler.sendMessage() существующей логикой handleMessage().Хранение этой работы на TCPComThread имеет дополнительное преимущество, заключающееся в том, что задания будут выполняться так же быстро, как они будут получены (они будут «самоудерживаться», поскольку каждое задание должно быть записано на диск, прежде чем будет получено новое).

...