2013-07-27 2 views
0

Я пишу приложение клиента/сервера Java. Он должен позволить клиентам отправлять текстовые данные на сервер. Такое общение должно повторяться много раз, используя одно и то же соединение.java - непрерывная передача данных через Socket

Я пишу это так:

// On a server: 
ServerSocket serverSocket = new ServerSocket(port); 
Socket socket = serverSocket.accept(); 
socket.setKeepAlive(true); 
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
if (reader.ready()) { 
    for (String line = reader.readLine(); line != null; line = reader.readLine()) { 
     // do something with line 
    } 
} 

// On a client: 
Socket socket = new Socket(host, port); 
socket.setKeepAlive(true); 
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
writer.write("Some data from client to server"); 
writer.flush(); 

Проблема в том, что я не могу читать на сервере, прежде чем я закрыть OutputStream на клиенте. Или я не могу снова открыть OutputStream на клиенте, если он уже был закрыт. Как я могу выполнять непрерывную отправку и чтение данных?

+2

Избавьтесь от теста ready(). Он ничего не добавляет, кроме ошибки. – EJP

ответ

2

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

+2

Здесь сообщение одностороннее. Зачем вам нужен дополнительный поток? – Joni

1

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

Да, вы можете. Вы просто не можете добраться до случая, когда readLine() возвращает значение null. Это не одно и то же.

Или я не могу открыть OutputStream на клиенте снова, если он уже был закрыт.

Конечно, нет. Вы должны создать новый Socket.

Как я могу выполнять непрерывную отправку и получение данных?

Непонятный вопрос. Код, который вы опубликовали, не пытается это сделать.

1

Если ваша цель - отправить много сообщений по одному и тому же соединению сокетов, эти сообщения должны быть разделены протоколом уровня приложения. Другими словами, вы не сможете рассчитывать на какие-либо системные вызовы, такие как reader.ready() или reader.readLine() == null, чтобы определить конец сообщения на сервере te.

Один из способов достижения этого - начать каждое сообщение с его длиной в символах. Затем сервер будет считывать именно это количество charecters, а затем останавливается и ждет нового сообщения. Другим является определение специальной последовательности символов, которая завершает каждое сообщение. Сервер будет реагировать на чтение этой конкретной последовательности, завершив чтение текущего сообщения и вернувшись к состоянию «wait for new message». Вы должны убедиться, что эта последовательность никогда не появляется в самом сообщении.