Java, получая странное исключение Socket: «Сломанный канал» и «Тайм-аут операции» - PullRequest
0 голосов
/ 11 ноября 2011

У меня есть клиент-серверное приложение, которое имеет 16 потоков (8 клиентов, 8 серверов), и у каждого есть соединение TCP в соответствии 1: 1 (так что 8 потоков TCP).

У меня есть сервер, который посылает X количество случайных байтов, а затем закрывается. Между тем клиент просто читает X данных, а затем закрывается. Х предопределен. Я также использую dummynet для регулирования пропускной способности, но я оставляю канал с достаточной пропускной способностью (100 Мбит / с). Иногда это работает нормально, иногда я получаю эти исключения. Я распределяю 1 ГБ по всем 8 соединениям примерно за 3,5 минуты.

Клиент выдает это исключение:

java.net.SocketException: Operation timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at miccbull.parralleltcp.client.StreamWorker.run(StreamWorker.java:43)

Сервер выдает это исключение:

java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:124)
at miccbull.parralleltcp.server.TransmissionWorker.run(TransmissionWorker.java:51)

Код сервера:

public void run() {

    OutputStream os = null;

    try {
        socket = sSocket.accept();
        os = socket.getOutputStream();
    } catch (IOException e2) {
        e2.printStackTrace();
    }

    //send the data
    for(int i = 0; i < Server.TRANSMISSIONS; i++){
        System.out.println(sSocket.getLocalPort() + " sending set " + (i+1) + " of " + Server.TRANSMISSIONS);

        try {
            os.write(new byte[Server.FILE_SIZE/Server.numStreams/Server.TRANSMISSIONS]);
            os.flush();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Closing server (at write bytes) with socket id: " + sSocket.getLocalPort());
        } 
    }

    System.out.println("Worker " + sSocket.getLocalPort() + " done");

    //close the socket
    try {
        socket.close();
        sSocket.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

Код клиента:

    public void run(){

    byte[] bytes = new byte[1024];  //number of bytes to read per client stream
    InputStream is = null;

    //connect to server
    try {
        connectionSocket = new Socket("localhost", id);
        is = connectionSocket.getInputStream();
    } catch (UnknownHostException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }


    //read file from server
    int value = 0;
    int bytesRead = 0;
    try {

        while(bytesRead < (Client.FILE_SIZE/Client.NUM_STREAMS)){
            value = is.read(bytes, 0, 1024);
            if(value == -1){
                System.out.println("******************************** Read is -1 for client " + id);
            }
            else if(value == 0){
                System.out.println("******************************** Read is 0 for client " + id);
            }
            bytesRead += value;
        }
    } catch (IOException e) {
        System.out.println("**** Exception in read in client " + id + " and value value was: " + value);
        if(bytesRead == (Client.FILE_SIZE/Client.NUM_STREAMS)){
            System.out.println("************ NOT ACTUALLY BAD" + id);
        }
        e.printStackTrace();
    }

    //Finished download
    Client.workerDone();
    System.out.println("Worker " + id + " done received " + bytesRead);

Что вызывает эти исключения?

Ответы [ 2 ]

0 голосов
/ 11 ноября 2011

Ваш клиент никогда не прекращает чтение, потому что вы не проверяете read (), возвращая <0. </p>

0 голосов
/ 11 ноября 2011

Вот что я вижу в вашем коде:

  1. Я проверил, что каждый вызов к socket.getOutputStream() и socket.getInputStream() возвращает другой поток, связанный с сокетом. Вы должны вызывать их каждый раз для каждого сокета и помещать результат в локальную переменную.

    OutputStream outputStream = socket.getOutputStream();
    // send the data
    for (int i = 0; i < 10; i++) {
        ....
        outputStream.write(...);
    
  2. Есть ряд мест, куда вы должны вернуться из вашего run() метода, но я подозреваю, что вы это знали.

  3. Вы не проверяете возвращаемое значение из read(), чтобы увидеть, возвращает ли оно -1 в EOF. Вы не должны просто предполагать, что вы получаете правильное количество байтов.

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

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