Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Socket в сетевом программировании
Socket — это абстракция для двусторонней коммуникации между процессами, как правило через сеть. Можно представить socket как "розетку" для подключения к сети. Socket позволяет приложениям обмениваться данными по протоколам TCP/IP, UDP и другим.
Основные типы сокетов
- TCP сокет (Stream Socket) — надёжная, упорядоченная доставка данных. Устанавливается соединение перед передачей. Используется для HTTP, FTP, Telnet.
- UDP сокет (Datagram Socket) — быстрая доставка, но без гарантий. Не требует установления соединения. Используется для видеотрансляции, онлайн игр, DNS.
- Unix domain socket — локальное взаимодействие между процессами на одной машине (файл или абстрактный namespace).
Как работает TCP сокет
На сервере:
- Создать socket
- Bind — привязать к адресу и порту
- Listen — слушать входящие соединения
- Accept — принять соединение и получить новый socket для клиента
- Read/Write — обмен данными
- Close — закрыть сокет
На клиенте:
- Создать socket
- Connect — подключиться к серверу (адрес + порт)
- Read/Write — обмен данными
- Close — закрыть сокет
Пример TCP сокета в Java
// Простой TCP сервер
import java.io.*;
import java.net.*;
public class SimpleServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("Сервер слушает на порту 8080");
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Клиент подключился: " + clientSocket.getInetAddress());
// Чтение данных от клиента
BufferedReader reader = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream())
);
String message = reader.readLine();
System.out.println("Получено: " + message);
// Отправка ответа
PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
writer.println("Эхо: " + message);
clientSocket.close();
}
}
}
// Простой TCP клиент
public class SimpleClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8080);
System.out.println("Подключился к серверу");
// Отправка сообщения
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
writer.println("Привет, сервер!");
// Получение ответа
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream())
);
String response = reader.readLine();
System.out.println("Ответ: " + response);
socket.close();
}
}
Пример UDP сокета
// UDP сервер
import java.net.*;
public class UDPServer {
public static void main(String[] args) throws Exception {
DatagramSocket socket = new DatagramSocket(9000);
byte[] buffer = new byte[1024];
while (true) {
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
socket.receive(packet); // Блокирует до получения пакета
String message = new String(packet.getData(), 0, packet.getLength());
System.out.println("Получено: " + message);
// Отправка ответа обратно
String response = "Спасибо за сообщение!";
DatagramPacket responsePacket = new DatagramPacket(
response.getBytes(),
response.length(),
packet.getAddress(),
packet.getPort()
);
socket.send(responsePacket);
}
}
}
Состояния TCP соединения
Sockets переходят через состояния ESTABLISHED → CLOSE_WAIT (при инициировании close) → CLOSED. При полной закрытии соединения обе стороны отправляют финальный ACK.
Важные параметры сокета
- SO_TIMEOUT — максимальное время ожидания данных
- SO_REUSEADDR — позволяет переиспользовать адрес/порт без ожидания
- SO_KEEPALIVE — периодические проверки живого соединения
- TCP_NODELAY — отключение буферизации (Nagle алгоритм)
- SO_RCVBUF, SO_SNDBUF — размеры буферов приёма/передачи
Потокобезопасность
Один socket не может одновременно читаться и писаться из разных потоков без синхронизации. Обычно используют:
- Один поток для read (блокирует)
- Один поток для write
- Или селекторы (NIO) для асинхронной работы с множеством сокетов
Масштабирование
Для работы с тысячами соединений используют:
- java.nio.SocketChannel — неблокирующие сокеты
- Selector — мониторинг множества каналов
- ExecutorService — пул потоков для обработки
Socket — фундаментальный примитив сетевого программирования, используется везде: от веб-серверов до игр и IoT систем.