Связь с сокетом Java - повышение скорости - PullRequest
2 голосов
/ 22 января 2012

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

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

Вот мой код:

Сервер

public class Server implements Runnable{
    static ServerSocket socket1;
    protected final static int port = 4701;
    static Socket connection;
    static StringBuffer process;

private String handleRequest(String req){
    if(req.equals("marco")){
        return "polo";
    }else
        return "null";

}

public void run(){
    try {
        socket1 = new ServerSocket(port);
        int character;

        while (true) {
            connection = socket1.accept();

            BufferedInputStream is = new BufferedInputStream(connection.getInputStream());
            InputStreamReader isr = new InputStreamReader(is);
            process = new StringBuffer();
            while ((character = isr.read()) != 13) {
                process.append((char) character);
            }
            String returnCode = handleRequest(process.toString()) + (char) 13;
            BufferedOutputStream os = new BufferedOutputStream(connection.getOutputStream());
            OutputStreamWriter osw = new OutputStreamWriter(os, "US-ASCII");
            osw.write(returnCode);
            osw.flush();
        }
    } catch (IOException e) {
        System.out.println("error starting server " + e.getMessage());
    }
    try {
        if(connection != null)
            connection.close();

    } catch (IOException e) {
    }

Клиент

    String host = "xx.xx.xx.xxx";
    int port = 4701;

    StringBuffer instr = new StringBuffer();

    try {
        InetAddress address = InetAddress.getByName(host);

        Socket connection = new Socket(address, port);

        BufferedOutputStream bos = new BufferedOutputStream(connection.
                getOutputStream());

            OutputStreamWriter osw = new OutputStreamWriter(bos, "US-ASCII");

            String process = "marco" + (char) 13;

            osw.write(process);
            osw.flush();

            BufferedInputStream bis = new BufferedInputStream(connection.
                getInputStream());

            InputStreamReader isr = new InputStreamReader(bis, "US-ASCII");

            int c;
            while ( (c = isr.read()) != 13)
              instr.append( (char) c);

            connection.close();
          }
          catch (Exception e){}

          if(instr.toString().equals("")){
              //error
          }


}

Так что дляНапример, я отправлю различные строки на сервер, чтобы определить, как сервер ответит.Так, например, как видно из кода, если я отправляю «marco» на сервер, я получаю «polo».У меня также есть (char) 13 в качестве разделителя, чтобы программа знала, что сообщение окончено.

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

Ответы [ 3 ]

4 голосов
/ 22 января 2012

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

Если вы действительно отчаянно нуждаетесь в малой задержке, тогда используйте DatagramSocket (т.е. UDP вместо TCP). Вы теряете гарантии доставки сообщений и должны ожидать потерянные пакеты, но для коротких сообщений в хорошей сети задержка настолько же высока, насколько вы можете получить для переносимого кода.

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

Микрооптимизация состояла бы в том, чтобы прекратить использование посимвольной обработки и сопоставить ваши «marco» и «polo» как байтовые строки. Но вряд ли это приведет к заметному улучшению.

1 голос
/ 22 января 2012

Сокеты довольно низкого уровня, поэтому я сомневаюсь, что есть гораздо более быстрые библиотеки Java, которые просты в использовании. Java может быть не самым быстрым языком, и самые популярные серверы обычно написаны на C / C ++. Однако есть много крупных проектов, работающих на серверах Java, Tomcat , Resin и JBoss и многие другие.

Когда дело доходит до оптимизации, обычный подход - сделать сервер многопоточным. После ServerSocket.accept () вы создаете новый поток для обработки запроса, чтобы сервер мог вернуться к обслуживанию других клиентов.

Вот хорошая статья, которая показывает многопоточные ответы на запросы сокетов

http://www.oracle.com/technetwork/java/socket-140484.html

1 голос
/ 22 января 2012

Есть много вещей, которые вы могли бы сделать по-другому, чтобы сделать это быстрее, но ясно, что вы должны изменить. Обычно самая длинная задержка в вашей сети.

Если бы вы подключались по шлейфу или с низкой задержкой, вы могли бы использовать NIO, и это могло бы быть намного быстрее. Но если вы используете обычную сеть, особенно если вы используете интернет-соединение, эффективность вашей программы не имеет большого значения.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...