установить опцию для сокетов в Java - PullRequest
0 голосов
/ 05 июня 2011

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

Моя проблема в том, что, когда я выключаю свой клиент, снова включаю его и пытаюсь восстановить соединение,он не будет подключаться (мой сервер остается включенным все время).

Чтобы восстановить соединение, я должен перезапустить свой сервер еще раз.

Поэтому я попытался сделать это на стороне сервера:

InetSocketAddress serverAddr = new InetSocketAddress(serverIpAddress, serverPort);
serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
//I tries setting up a reuse option     
serverSocket.bind(serverAddr);

Даже после setReuseAddress() мой клиент не подключится, пока я не перезапущу свой сервер!Кто-нибудь знает, как это можно сделать?

EDIT2:

    try {
        while(true){

        clientSocket = serverSocket.accept();

        System.out.println("S-a conectat clientul de monitorizare!");


        os=new ObjectOutputStream(clientSocket.getOutputStream());
        try{

            coord=(Coordinate)queue.take();
            System.out.println(coord.getLat()+coord.getLon()+coord.getVit()+coord.getwId()+coord.getime());
        os.writeObject(coord);

        os.flush();


        }

        catch(Exception e)

        {
            e.printStackTrace();

        }
        }

    } catch (IOException e) {

        System.out.println(e);

         try {

                clientSocket.close();

                os.close();

             }catch(Exception e1) {

               e1.printStackTrace();

             }

    }

Новое редактирование:

Сервер пула потоков:

Main:

Сервер ThreadPooledServer = новый ThreadPooledServer (очередь, 7001);новый поток (сервер) .start ();


ThreadPooledServer:

открытый класс ThreadPooledServer реализует Runnable {

 protected ExecutorService threadPool =
        Executors.newFixedThreadPool(5);


public void run() {

    openServerSocket();

    while (!isStopped()) {
        Socket clientSocket = null;
        try {
            System.out.println("Serverul asteapta clienti spre conectare");
            clientSocket = this.serverSocket.accept();
            clientconnection++;
            System.out.println("Serverul a acceptat clientul cu numarul:"
                    + clientconnection);


        } catch (IOException e) {
            if (isStopped()) {
                System.out.println("Server Stopped.");
                return;
            }
            throw new RuntimeException("Error accepting client connection",
                    e);
        }

    WorkerRunnable workerRunnable = new WorkerRunnable(queue,clientSocket);
    this.threadPool.execute(workerRunnable);

    }

    System.out.println("Server Stopped.");
}

открытый синхронизированный void stop () {this.isStopped = true;

    try {

    this.threadPool.shutdown();

    }


    catch (IOException e) {
        throw new RuntimeException("Error closing server", e);
    }

}

private void openServerSocket () {

    try {

        InetSocketAddress serverAddr = new InetSocketAddress(SERVERIP,
                serverPort);

        serverSocket = new ServerSocket();

        serverSocket.setReuseAddress(true);
        serverSocket.bind(serverAddr);

    } catch (IOException e) {
        throw new RuntimeException("Cannot open port", e);
    }
}

 this.serverSocket.close();

Ответы [ 2 ]

2 голосов
/ 05 июня 2011

В вашем методе run вы принимаете один клиент и затем входите в бесконечный цикл, пытаясь записать данные в ObjectOutputStream.Когда клиент закрывает соединение, выдается исключение, потому что вы больше не можете записывать в поток.На этом этапе мы находимся в бесконечном цикле (while(true) { .. }), и метод run заканчивается.

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

Псевдо-код ниже (примечание: я не ловлю никаких исключений и т. д.):

while (true)
{
    // Wait for a client to connect..
    Socket clientSocket = serverSocket.accept();

    // Write to the client..
    ObjectOutputStream os = new ObjectOutputStream(clientSocket.getOutputStream());
    os.writeObject(coord);
    os.flush();
}
1 голос
/ 05 июня 2011

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

Поток прослушивания сервера (основной поток)

try {
   create server socket and bind to port
   while server is online
      listen for incoming connections
      if the client connection is accepted [1]
         start client thread
catch exception
   handle exception
finally
   make sure the server socket is disconnected
   cleanup

Поток подключения к клиентскому серверу

write to client socket to initialize connection
try
   while scoket is opened
      read data
      data treatment
      write response
 catch exceptions
    handle exception [2]
 finally
    close client socket
    cleanup

[1] если ваш сервер обрабатывает только одного клиента, он должен отказаться от соединения, поэтому клиент не ждет без причины

[2] , если исключение не относится к сокету, клиент должен быть предупрежден окончательной записью в сокет перед его закрытием

Поток клиента (на стороне клиента)

try
   connect to server
   protocol handshake (optional) [4]
   while socket is connected
      client server communication
catch exception
    handle excpetion
finally
    close socket

[4] , поскольку сервер должен сначала выполнить запись в сокет, клиент должен прочитать из него любое приветственное сообщение или ошибкусообщения перед попыткой что-либо написать.

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