← Назад к вопросам

Что такое Socket?

2.0 Middle🔥 181 комментариев
#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Socket в сетевом программировании

Socket — это абстракция для двусторонней коммуникации между процессами, как правило через сеть. Можно представить socket как "розетку" для подключения к сети. Socket позволяет приложениям обмениваться данными по протоколам TCP/IP, UDP и другим.

Основные типы сокетов

  1. TCP сокет (Stream Socket) — надёжная, упорядоченная доставка данных. Устанавливается соединение перед передачей. Используется для HTTP, FTP, Telnet.
  2. UDP сокет (Datagram Socket) — быстрая доставка, но без гарантий. Не требует установления соединения. Используется для видеотрансляции, онлайн игр, DNS.
  3. Unix domain socket — локальное взаимодействие между процессами на одной машине (файл или абстрактный namespace).

Как работает TCP сокет

На сервере:

  1. Создать socket
  2. Bind — привязать к адресу и порту
  3. Listen — слушать входящие соединения
  4. Accept — принять соединение и получить новый socket для клиента
  5. Read/Write — обмен данными
  6. Close — закрыть сокет

На клиенте:

  1. Создать socket
  2. Connect — подключиться к серверу (адрес + порт)
  3. Read/Write — обмен данными
  4. 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 переходят через состояния ESTABLISHEDCLOSE_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 систем.