Socket.getInputStream: примеры (JAVA)
Socket.getInputStream: InputStreamОбщее описание
Метод Socket.getInputStream() возвращает объект java.io.InputStream, позволяющий читать входящие байты из установленного TCP-соединения. Использование актуально в клиентских и серверных приложениях при работе с потоковой передачей данных по протоколу TCP.
Ключевые свойства и поведение:
- Аргументы: метод не принимает аргументов.
- Возвращаемое значение:
InputStream- поток для чтения байт из сокета. - Исключения: бросает
IOException, если сокет закрыт или возникли ошибки ввода/вывода при получении потока. - Блокировка: чтение из возвращенного потока блокирует вызывающий поток до появления данных или EOF, если не установлен таймаут (
setSoTimeout). - Повторные вызовы: несколько вызовов
getInputStream()обычно возвращают один и тот же объект потока, соответствующий сокету. - Закрытие: закрытие возвращенного
InputStreamприведет к закрытию соответствующего сокета. Аналогично, закрытие сокета закроет поток. - Совместимость: для неблокирующих операций применяются NIO API (
SocketChannel), а неgetInputStream().
Рекомендуемые практики: чтение в цикл до возврата -1 (EOF), использование буферов (например, BufferedInputStream), явное закрытие ресурсов в блоке try-with-resources и обработка SocketTimeoutException при установленном таймауте.
Короткие примеры
Пример 1. Простой клиент, читающий строку от сервера (байтово-кодировка UTF-8):
import java.io.*;
import java.net.*;
public class SimpleClient {
public static void main(String[] args) throws Exception {
try (Socket s = new Socket("localhost", 12345);
InputStream in = s.getInputStream();
InputStreamReader isr = new InputStreamReader(in, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
String line = br.readLine();
System.out.println(line);
}
}
}
Пример вывода (если сервер отправил "Hello\n"): Hello
Пример 2. Чтение бинарных данных в буфер до EOF:
import java.io.*;
import java.net.*;
public class ReadBytes {
public static void main(String[] args) throws Exception {
try (Socket s = new Socket("example.com", 80);
InputStream in = s.getInputStream()) {
byte[] buf = new byte[4096];
int read;
while ((read = in.read(buf)) != -1) {
// обработка buf[0..read-1]
}
}
}
}
Если соединение закроет удаленная сторона, цикл завершится (EOF).
Пример 3. Таймаут чтения с обработкой SocketTimeoutException:
Socket s = new Socket();
s.connect(new InetSocketAddress("host", 9000), 2000); // connect timeout
s.setSoTimeout(3000); // read timeout
try (InputStream in = s.getInputStream()) {
int b = in.read(); // бросит SocketTimeoutException если данных нет 3 сек
} catch (java.net.SocketTimeoutException e) {
System.out.println("read timed out");
}
read timed out
Похожие API в Java
- Socket.getOutputStream() - для записи в соединение; часто используется вместе с
getInputStream(). - SocketChannel (NIO) - поддерживает неблокирующие операции, селекторы и масштабируемые сервера. Предпочтительнее при высокой нагрузке и необходимости неблокирующего ввода-вывода.
- InputStream-обертки (
BufferedInputStream,DataInputStream,ObjectInputStream) - облегчают чтение примитивов, объектов или повышают производительность за счет буферизации. - SSLSocket - для защищенных соединений; предоставляет тот же метод
getInputStream(), но с шифрованием и установкой TLS.
Выбор между ними зависит от требований: для простоты и синхронного кода достаточно getInputStream(); для асинхронной или масштабируемой обработки - NIO; для защищенных каналов - SSL.
Аналоги в других языках
- Python:
socket.recv()или файл-объектsocket.makefile().read().import socket s = socket.create_connection(("example.com", 80)) s.sendall(b"GET / HTTP/1.0\r\nHost: example.com\r\n\r\n") print(s.recv(1024))b'HTTP/1.0 200 OK\r\n...'
- JavaScript (Node.js):
net.Socketи событие'data':const net = require('net'); const socket = net.createConnection(80, 'example.com'); socket.on('data', (chunk) => console.log(chunk.toString()));HTTP-ответ в консоли
- PHP:
fsockopen/stream_socket_clientиfread/stream_get_contents.$s = stream_socket_client("tcp://example.com:80"); fwrite($s, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n"); echo fread($s, 1024);HTTP-ответ
- C#:
System.Net.Sockets.NetworkStreamчерезTcpClient.GetStream()илиSocket.Receive().using (var client = new TcpClient("example.com", 80)) { using (var stream = client.GetStream()) { byte[] buf = new byte[1024]; int read = stream.Read(buf, 0, buf.Length); } }HTTP-ответ в буфере
- Go: интерфейс
net.Connи методRead:conn, _ := net.Dial("tcp", "example.com:80") fmt.Fprint(conn, "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n") b := make([]byte, 1024) n, _ := conn.Read(b) fmt.Println(string(b[:n]))HTTP-ответ
- Lua: библиотека LuaSocket -
tcp:receive().local socket = require('socket') local c = assert(socket.tcp()) c:connect('example.com', 80) c:send('GET / HTTP/1.0\r\nHost: example.com\r\n\r\n') local s = c:receive('*l') print(s)HTTP-строка
Отличия от Java: в разных языках API бывает синхронным событийным или блокирующим. Java предоставляет как блокирующие потоки (getInputStream()), так и более низкоуровневую NIO-модель для неблокирующего ввода-вывода.
Типичные ошибки и примеры
Ниже несколько распространенных проблем при работе с getInputStream().
Ошибка 1. Ожидание данных без таймаута (висит навсегда).
Socket s = new Socket("remote", 9000);
InputStream in = s.getInputStream();
int b = in.read(); // блокируется, если сервер ничего не отправляет
Программа может зависнуть бесконечно, если удаленная сторона не отправляет данные.
Ошибка 2. Некорректная проверка available() для чтения всех данных.
int avail = in.available();
byte[] buf = new byte[avail];
in.read(buf); // может прочитать меньше байт или 0
// неверное предположение: available() == полный размер сообщения
available() возвращает количество байт, которые можно прочитать без блокировки, но не гарантию полного сообщения.
Ошибка 3. Закрытие только InputStream без явного управления ресурсами в старом коде (утечка при исключениях).
InputStream in = s.getInputStream();
try {
// чтение
} finally {
in.close(); // если сокет открыт иначе возможны ошибки
}
// надежнее: try-with-resources при создании сокета и потока
Риск оставить сокет открытым или удвоенно закрыть ресурс. Лучше использовать try-with-resources.
Ошибка 4. Попытка прочитать после shutdownOutput/закрытия сокета.
s.shutdownOutput();
int x = s.getInputStream().read(); // поведение зависит от удаленной стороны
// возможно EOF или IOException
Если удаленная сторона закрыла соединение, read вернет -1; если локальный сокет закрыт - IOException.
Изменения и примечания по версиям
Сигнатура Socket.getInputStream() остается стабильной с ранних версий Java. Основные улучшения в экосистеме связаны не с самим методом, а с сопутствующими API:
- Добавлены удобные методы в
InputStreamначиная с Java 9:readNBytes,transferTo,readAllBytes, которые упрощают обработку потоков, возвращаемыхgetInputStream(). - NIO и AsynchronousSocketChannel предоставляют альтернативы для неблокирующего и асинхронного ввода-вывода.
- В Java 9+ с модульной системой зависимости модулей могут влиять на доступность некоторых классов в ограниченных окружениях, но базовый метод остается доступным в стандартных модулях.
Расширенные и нестандартные примеры
1) Использование readNBytes (Java 9+) для точного чтения фиксированного размера сообщения:
try (Socket s = new Socket("host", 7000);
InputStream in = s.getInputStream()) {
byte[] msg = in.readNBytes(1024); // вернет ровно 1024 или меньше при EOF
System.out.println("прочитано: " + msg.length);
}
прочитано: 1024
2) Пример протокола с длиной в начале (length-prefix) и обработкой частичных чтений:
// Чтение сообщения: сначала 4 байта длины (big-endian), затем тело
try (Socket s = new Socket("host", 8000);
InputStream in = s.getInputStream()) {
byte[] lenBuf = in.readNBytes(4);
if (lenBuf.length < 4) throw new EOFException();
int len = ((lenBuf[0] & 0xFF) << 24) | ((lenBuf[1] & 0xFF) << 16)
| ((lenBuf[2] & 0xFF) << 8) | (lenBuf[3] & 0xFF);
byte[] body = in.readNBytes(len);
// обработка body
}
Если удаленная сторона отправила корректный пакет, body.length == len.
3) Комбинация с SSL: чтение зашифрованных данных через SSLSocket:
SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
try (SSLSocket ss = (SSLSocket) f.createSocket("secure.example", 443);
InputStream in = ss.getInputStream()) {
// чтение как обычно, TLS-расшифровка внутри SSLSocket
byte[] buf = new byte[4096];
int r = in.read(buf);
}
Данные приходят уже в расшифрованном виде.
4) Half-close: явный shutdownOutput на стороне клиента и продолжение чтения ответа сервера:
try (Socket s = new Socket("host", 8080)) {
OutputStream out = s.getOutputStream();
out.write(requestBytes);
s.shutdownOutput(); // сигнал энд-клиента
InputStream in = s.getInputStream();
// читать ответ сервера, пока не EOF
}
Сервер получает EOF на входе и может отправить ответ; клиент читает до -1.
5) Использование InputStream.transferTo для простой переадресации в файл (Java 9+):
try (Socket s = new Socket("host", 9001);
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("out.bin")) {
in.transferTo(fos);
}
Весь поток записи сокета сохраняется в файле до EOF.
6) Комбинация NIO и потоков: когда нужен неблокирующий режим, использовать SocketChannel и ByteBuffer, а не getInputStream(). Пример: мультиплексирование через Selector для множества соединений.
джава Socket.getInputStream function comments
- джава Socket.getInputStream - аргументы и возвращаемое значение
- Функция java Socket.getInputStream - описание
- Socket.getInputStream - примеры
- Socket.getInputStream - похожие методы на java
- Socket.getInputStream на javascript, c#, python, php
- Socket.getInputStream изменения java
- Примеры Socket.getInputStream на джава