Java предоставляет два класса протокола TCP, которые используются в программировании на стороне клиента и программировании на стороне сервера соответственно. Прежде чем приложение начнет связь, сначала необходимо создать соединение, инициированное клиентской программой, а серверная программа должна всегда прослушивать определенный номер порта хоста, ожидая соединения клиента; В клиенте нам нужно использовать только экземпляры Socket, в то время как серверу необходимо обрабатывать как экземпляры ServerSocket, так и экземпляры Socket, которые используют OutputStream и InpuStream для отправки и получения данных;
Лучший способ получить какие-то знания — использовать их. Из предыдущих заметок мы уже знаем, как получить информацию об адресе хоста. Теперь мы используем простую программу для первоначального изучения программирования сокетов с использованием протокола TCP в транспорте. слой.
TCP-серверная часть
В программировании сокетов серверная часть намного сложнее клиентской. Задача сервера — установить терминал связи и пассивно ожидать подключения клиента. Следующий пример серверной программы используется для прослушивания номера порта, полученного из ввода консоли, и отправки сообщения, отправленного клиентом, обратно.
Скопируйте код кода следующим образом:
importjava.net.*;
importjava.text.MessageFormat;
importjava.io.*;
publicclassTCPEchoServer{
PrivatestaticfinalintBUFSIZE=32;
publicstaticvoidmain(String[]args)throwsIOException {
//TODOАвтоматически сгенерированная заглушка метода
//Получаем номер порта для мониторинга из консоли
если(args.length!=1)
thrownewIllegalArgumentException("Параметр(ы):<Порт>");
//Получаем номер порта
intservPort=Integer.parseInt(args[0]);
//Создаем экземпляр объекта ServerSocket
ServerSocketservSocket = новыйServerSocket (servPort);
System.out.println(MessageFormat.format("Начать прослушивание, номер порта: {0}",args[0]));
//Общее количество байт исходных полученных данных
intrecvMsgSize;
//буфер для приема данных
байт[]receiveBuf=newbyte[BUFSIZE];
//Итерация цикла, прослушивание номера порта и обработка новых запросов на соединение
в то время как (правда) {
//Блокируем и ждем, создаем новый экземпляр соединения каждый раз при получении запроса
SocketclntSocket=servSocket.accept();
//Получаем SocketAddress подключенного клиента
SocketAddressclientAddress=clntSocket.getRemoteSocketAddress();
//Распечатываем информацию об адресе клиента подключения
System.out.println("Handlingclientat"+clientAddress);
//Объект, получающий данные от клиента
InputStreamin=clntSocket.getInputStream();
//Объект, который отправляет данные клиенту
OutputStreamout=clntSocket.getOutputStream();
//После чтения данных, отправленных клиентом, отправляем их клиенту
while((recvMsgSize=in.read(receiveBuf))!=-1){
out.write(receiveBuf,0,recvMsgSize);
}
//Когда клиент закрывает соединение, закрываем соединение
System.out.println("Клиент закрывает соединение");
clntSocket.close();
}
}
}
TCP-клиент
При программировании сокетов сначала клиенту необходимо отправить сообщение на сервер, а затем пассивно дождаться ответа сервера. В следующем примере: мы отправляем информацию на сервер, ждем сообщения, отправленного сервером, и распечатываем его.
Скопируйте код кода следующим образом:
importjava.io.*;
importjava.net.Socket;
importjava.net.SocketException;
publicclassTCPEchoClient{
publicstaticvoidmain(String[]args)throwsIOException {
//TODOАвтоматически сгенерированная заглушка метода
//Определяем корректность полученных с консоли параметров
if((args.length<2)||(args.length>3))
thrownewIllegalArgumentException(
«Параметры:<Сервер><Слово>[<Порт>]]»);
//Получаем адрес сервера
Stringserver=args[0];
//Получаем информацию, которую необходимо отправить
byte[]data=args[1].getBytes();
//Если есть три параметра подчиненного устройства, получаем номер порта для отправки информации. Номер порта по умолчанию — 8099.
intservPort=(args.length==3)?Integer.parseInt(args[2]):8099;
//Создаем экземпляр экземпляра Socket на основе адреса сервера и номера порта
Socketsocket = newSocket (сервер, servPort);
System.out.println("Подключено к серверу...отправка_строки");
//Возвращаем входной поток этого сокета, который является объектом данных, полученным от сервера
InputStreamin=socket.getInputStream();
//Возвращаем выходной поток этого сокета, который является объектом данных, отправленным на сервер
OutputStreamout=socket.getOutputStream();
//Отправляем данные, полученные с консоли, на сервер
out.write(данные);
//Счетчик, получающий данные, запишет начальное смещение данных
inttotalBytesRcvd=0;
//Инициализируем общее количество байт полученных данных
интбайтесРквд;
while(totalBytesRcvd<data.length){
//Если сервер закрывает соединение, он возвращает -1. Метод read возвращает общее количество байт полученных данных.
if((bytesRcvd=in.read(data,totalBytesRcvd,data.length
-totalBytesRcvd))==-1)
thrownewSocketException("Соединение с сервером закрыто");
totalBytesRcvd+=bytesRcvd;
}
//Распечатываем данные, отправленные сервером
System.out.println("Получено:"+newString(данные));
//Закрываем соединение
сокет.закрыть();
}
}
Сначала запустите сервер и прослушайте порт 8099:
Затем запустите клиентскую программу и отправьте сообщение на сервер:
Снова взглянув на нашу серверную консоль, мы можем увидеть информацию об адресе предыдущего клиентского соединения: