Ошибка записи в сокет TCP - PullRequest
2 голосов
/ 10 августа 2011

Что не так с этим простым примером сервера / клиента Java TCP?

Сначала запустите сервер:

import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    public static void main(String[] args) throws Throwable {
        ServerSocket ss = new ServerSocket(2345);
        Socket s = ss.accept();
        OutputStream os = s.getOutputStream();
        Thread.sleep(5000);
        for (int i = 0; i < 3; i++) {
            os.write("A".getBytes());
            os.flush();
            System.out.println("Written in cycle " + i);
        }
        os.close();
        s.close();

    }

}

Запустите клиент и просмотрите сервер после этого:

import java.net.Socket;

public class Client {

    public static void main(String[] args) throws Throwable{
        Socket s=new Socket("localhost",2345);
        s.close();
        System.out.println("Closed");
    }

}

Клиентский сокет немедленно закрывается. Однако операция записи сокета на сервере завершается неудачно во втором цикле, т. Е. Первая запись не вызывает исключение.

Это вывод выполнения сервера:

Written in cycle 0
Exception in thread "main" java.net.SocketException: Software caused connection abort: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:124)
    at Server.main(Server.java:16)

Ответы [ 4 ]

2 голосов
/ 11 августа 2011

Следующая ссылка соответствует вопросу 100% и объясняет, в чем заключается проблема и как ее решить:

http://download.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html

Итак, чтобы быть более точным в отношении приведенного выше кода,установка LINGER в 0 решит проблему:

import java.net.Socket;

public class Client {

    public static void main(String[] args) throws Throwable {
        Socket s = new Socket("localhost", 2345);
        s.setSoLinger(true, 0);
        s.close();
    }

 }
2 голосов
/ 10 августа 2011

Ваш клиент подключается и сразу закрывается.Это обнаруживается сервером, который отказывается писать в «никуда».

1 голос
/ 10 августа 2011

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

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

0 голосов
/ 10 августа 2011

Скопировано из комментариев, поскольку оно отвечает на ваш вопрос.

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

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