Java Socket: Создание клиент-серверного приложения для чата
В этом руководстве вы узнаете, как создать приложение java-чата между двумя компьютерами с помощью сокетов. Прежде чем приступить к программированию, вам нужно настроить свою сеть так, чтобы эти две машины взаимодействовали, например, в локальной сети вашего дома. Мы собираемся реализовать то, что мы видели в теории: хорошо известную клиент-серверную модель.К концу этого урока вы узнаете, как сокеты могут обмениваться сообщениями.
Server
javaserver> инициализирует соединение, прослушивает порт и ожидает принятия входящих соединений. Например, номер порта 5000, клиент отправляет запрос на сервер с этим номером порта 5000. Сервер принимает запрос и передает свою информацию (IP-адрес) клиенту. Теперь соединение установлено и можно обмениваться сообщениями.Java предоставляет пакет java.net который обрабатывает все сетевые операции, вам нужны только два класса:
- java.net.ServerSocket: Этот класс принимает соединения от clients.
- java.net.Socket: Этот класс подключается к удаленному компьютеру.
- Сканирование: Чтение ввода с клавиатуры.
- BufferedReader: чтение текста, полученного от sender.
- PrintWriter: отправить набранный текст.
ServerSocket socketserver;После создания серверного сокета с номером порта 5000 сервер ожидает входящих соединений, и как только одно из них обнаружено, принимает его. Две переменные, которые обрабатывают поток чтения и записи in и out инициализируются для прямой связи с потоком отправки и приема.
Сокет сервера;
final BufferedReader in;
окончательный выход PrintWriter;
final Сканер sc=new Сканер(System.in);
try {
socketserver = new ServerSocket(5000);
serversocket = socketserver.accept();
out = new PrintWriter(serversocket.getOutputStream());
in = new BufferedReader (new InputStreamReader (serversocket.getInputStream()));
Строка s;
s = sc.next();
out.println(s);
out.flush();
Строка message_client;
message_client = in.readLine();
System.out.println("Клиент: "+message_client);
}
catch (IOException e) {
e.printStackTrace();
}
Переменная с хранит текст, набранный с помощью next(), а затем отправляется с println(s).
Метод flush() важен, потому что он сбрасывает буфер записи в вывод, в противном случае null будет получено другой машиной.
Переменная message_client хранит сообщение квитанция, отображаемая с println().
Ограничением этого кода является то, что он может отправить и получить сообщение только один раз. У вас в голове появится идея: добавить цикл while(true). Это так, но если, например, сервер отправляет сообщение клиенту, клиент не может получить сообщение, пока не отправит его тоже. Оптимальным решением является создание двух потоков: один для отправки, а другой для получения. Оба этих процесса позволяют отправлять и получать файлы одновременно.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/*
* www.codeurjava.com
*/
public class Server {
public static void main(String[] test) {
final ServerSocket serverSocket;
final Socket clientSocket;
final BufferedReader in;
окончательный выход PrintWriter;
Сканер sc=new Сканер(System.in);
try {
serverSocket = new ServerSocket(5000);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader (new InputStreamReader (clientSocket.getInputStream()));
Thread send= new Thread(new Runnable() {
String msg;
@Override
public void run() {
while(true){
msg = sc.nextLine();
out.println(msg);
out.flush();
}
}
});
send.start();
Thread receive= new Thread(new Runnable() {
String msg;
@Override
public void run() {
try {
msg = in.readLine();
//пока клиент подключен
while(msg!=null){
System.out.println("Client: "+msg);
msg = in.readLine();
}
//выходим из цикла, если клиент деконected
System.out.println("Клиент деконectирован");
//закрыть поток и сессию socket
out.close();
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
receive.start();
}catch (IOException e) {
e.printStackTrace();
}
}
}
Разделение двух процессов понятно, Сервер и Клиент могут обмениваться данными в любое время и бесконечно. Цикл воспроизведения while проверяет, установлено ли соединение. Не забудьте закрыть потоки чтения и записи, а также соединение после выхода из цикла с помощью метода close().
Client
Client требуется только Socket для установки соединения server, на конструктор принимает в качестве входных данных IP-адрес сервера и номер порта. Остальной код такой же, как и у server.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/*
* www.codeurjava.com
*/
public class Client {
public static void main(String[] args) {
final Socket clientSocket;
final BufferedReader in;
окончательный выход PrintWriter;
final Scanner sc = new Scanner(System.in);//для чтения с клавиатуры
try {
/*
* информация о сервере ( порт и IP-адрес или имя хоста
* 127.0.0.1 - это локальный адрес машины
*/
clientSocket = new Socket("127.0.0.1", 5000);
//поток для отправки
out = new PrintWriter(clientSocket.getOutputStream());
//поток для получения
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
Thread send = new Thread(new Runnable() {
String msg;
@Override
public void run() {
while(true){
msg = sc.nextLine();
out.println(msg);
out.flush();
}
}
});
send.start();
Получить поток = new Thread(new Runnable() {
Строка msg;
@Override
public void run() {
try {
msg = in.readLine();
while(msg!=null){
System.out.println("Server: "+msg);
msg = in.readLine();
}
System.out.println("Отключенный сервер");
out.close();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
receive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Execution:
Примечание: Если вы работаете на одной и той же машине, вы должны запустить Eclipse дважды, один для сервера, а другой для клиента. Посмотрите следующее видео на YouTube:
https://www.youtube.com/watch?v=d-eD6EDa3io
References:
Network in Java - Манипулирование IP-адресами
как получить имя и локальный IP-адрес сервера/клиента
Openclassrooms: Введение в сокеты
Java doc: Class Socket
![]() |
Окно сервера |
![]() |
Client window |
https://www.youtube.com/watch?v=d-eD6EDa3io
References:
Network in Java - Манипулирование IP-адресами
как получить имя и локальный IP-адрес сервера/клиента
Openclassrooms: Введение в сокеты
Java doc: Class Socket