TCP-связь один-ко-многим - PullRequest
       29

TCP-связь один-ко-многим

2 голосов
/ 25 марта 2011

Я пытаюсь собрать базовое доказательство Java-концепции, чтобы иметь сервер (который, скорее всего, будет просто ноутбуком с Windows или Linux), который может отправлять сообщения на несколько устройств Android, подключенных к WIFI, на одном и том жеподсеть (изначально 20-30, но это может быть довольно большое число в будущем - 2 или 300? - не уверен, но мне нужно учесть такую ​​возможность).Приложение отправит сообщение на все устройства (изначально одно и то же сообщение, но я могу разрешить специальные случаи где-нибудь в будущем).Затем каждое устройство может ответить, и я захочу проверить, какие из них ответили, и сохранить ответы.

Я попробовал некоторый тестовый код с использованием UDP (с некоторой помощью из учебника на nakov.com), но это было оченьненадежный и телефон часто зависал при попытке получить пакет - хотя иногда он работал отлично.Мой код клиента для устройства Android показан ниже для справки (обратите внимание, этот код просто отправляет запрос на сообщение, а затем получает и отображает его - у меня не было времени написать его так, как я хотел, так как он не 'В любом случае, он кажется достаточно надежным для использования).

Итак, я думаю, что мне, вероятно, нужно использовать TCP для надежности (хотя я открыт для предложений).Будет ли в порядке 2-300 отдельных одновременных соединений TCP?И вполне вероятно, что все ответы будут поступать на сервер одновременно (или в течение 10-15 секунд), не затопит ли это таким образом, что не сможет справиться?Вероятно, это будет хорошо только для 20-30 устройств?

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

Приветствия

Стив

Клиентское приложение UDP:

package nz.co.et.quoteclient;

import java.io.IOException;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class QuoteClient extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Button button = (Button) findViewById(R.id.Button01);

        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                if (wifiManager.isWifiEnabled()) {

                    TextView errorText = (TextView) findViewById(R.id.TextView01);
                    int serverPort = 4445;
                    InetAddress address = null;
                    try {
                        address = InetAddress.getByName("192.168.1.4");
                    } catch (UnknownHostException e) {
                        errorText.setText("Failed at setting server IP Address");
                        e.printStackTrace();
                    }

                    byte[] buf = new byte[256];
                    DatagramPacket packet = new DatagramPacket(buf, buf.length, address, serverPort);

                    DatagramSocket socket = null;
                    try {
                        socket = new DatagramSocket();
                    } catch (SocketException e) {
                        errorText.setText("Failed at creating socket");
                        e.printStackTrace();
                    }
                    try {
                        socket.send(packet);
                    } catch (IOException e) {
                        errorText.setText("Failed at sending request packet");
                        e.printStackTrace();
                    }

                    // get response
                    packet = new DatagramPacket(buf, buf.length);
                    try {
                        socket.receive(packet);
                    } catch (IOException e) {
                        errorText.setText("Failed at receiving quote packet from server");
                        e.printStackTrace();
                    }

                    // display response
                    String message = new String(packet.getData());
                    String data = "";
                    for (int i = 0; i < message.length(); i++) {
                        int tmp = (int) message.charAt(i);
                        data = (tmp <= 0 || tmp >= 256) ? data += "" : data + message.charAt(i);
                    }
                    Toast.makeText(getApplicationContext(), data, Toast.LENGTH_LONG).show();
                    // errorText.setText(data);
                }

                else {
                    Toast.makeText(getApplicationContext(), "WIFI not enabled", Toast.LENGTH_LONG).show();
                }
            }
        });
    }
}

Ответы [ 2 ]

3 голосов
/ 25 марта 2011

TCP, безусловно, будет более надежным, чем UDP, поскольку UDP не гарантирует доставку пакетов (возможно, именно поэтому ваше приложение зависает на приеме).

2-300 соединений должны быть управляемыми,но это будет зависеть от таких вещей, как ваши аппаратные возможности и количество данных, которые обрабатываются / отправляются туда и обратно.

Вам также придется принять несколько решений по таким вещам, как:

  • На каком языке вы пишете свой сервер (java?)?

  • Поддерживаете ли вы постоянное соединение клиента с сервером или воссоздаете его?каждый раз?

  • Кто отвечает за установление соединения (клиент или сервер)?

  • Как сервер собирается определить, какойУстройство получило сообщение, связано ли оно с IP-адресом, или происходит какое-либо подтверждение связи для идентификации клиентов.

  • Если клиент становится подключенным, выполните yВам нужно отправить всю ранее пропущенную информацию?

  • Нужно ли получать информацию обо всех клиентах одновременно или она может быть в шахматном порядке?

  • Как ведет себя ваше клиентское приложение, если оно теряет соединение, повторяет ли оно попытку и т. Д.?

И этот список можно продолжить ...

2 голосов
/ 25 марта 2011

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

Если вы выберете многопоточность, вы не сможете масштабировать больше 100 клиентов; каждый поток приносит с собой достаточно памяти для хранения каждого потока и планирования, что я действительно не хотел бы рассчитывать на это помимо 50 клиентов.

Новая Java NIO платформа предоставляет некоторые функциональные возможности, которые можно использовать для масштабирования в сотни или тысячи одновременных подключений. Если каркас использует select(2) под капотом, он должен иметь возможность выполнять более 1000 одновременных подключений, но если он использует epoll(2) или kqueue или аналогичные конструкции, тогда даже более 1000 одновременных подключений должны быть осуществимы.

То, что вы делаете с этими сеансами, может диктовать гораздо меньшее количество одновременных подключений: потоковое видео будет более интенсивным, чем отправка милой вежливой страницы "Добро пожаловать в нашу сеть".

...