Руководство Программирование Java Socket

1- Что такое Socket?

На стороне сервера (server-side):
  • Обычно сервер работающий на определенном компьютере, имеет серверный сокет (Server Socket), привязанный к определенному номеру порта (Port number). Серверные программы (Server program)  просто ждут, слушая серверный сокет (Server Socket) для клиента, чтобы выполнить запрос соединения.
На стороне клиента (client-side):
  • Клиент знает имя машины, на которой работает сервер (server), и номер порта, на котором сервер прослушивает. Чтобы сделать запрос на соединение, клиент пытается встретиться с сервером на компьютере и в порту сервера. Клиент также должен идентифицировать себя с сервером, чтобы он связался с локальным портом, который будет использоваться во время этого соединения. Обычно это назначается операционной системой.
Общая иллюстрация:
Если все пройдет хорошо, серверная программа  (server program) примет соединение клиента. После принятия сервер получает новый сокет, привязанный к тому же локальному порту, а также его удаленная конечная точка (remote endpoint) является адресом и портом клиента. Он создал новый сокет, чтобы заботиться о клиента, который только что принял соединение, и мог продолжать прослушивать исходный сокет (ServerSocket) для других запросов на подключение.
На стороне клиента, если соединение принято, сокет успешно создается, и клиент может использовать сокет для связи с серверной программой.

Теперь клиент и сервер могут взаимодействовать, записывая или читая их сокеты (Socket).
Данные, записанные в выходной поток на Socket клиента, будут поступать на входной поток Socket на сервере. И наоборот, данные, записываемые в выходной поток на Socket на сервере, будут передаваться в входной поток  Socket клиента.
Определение:

Socket является одной конечной точкой двухсторонней линии связи между двумя программами, запущенными в сети. Socket привязан к номеру порта (определенный номер), чтобы уровни  TCP (TCP Layer)​​​​​​​ могли идентифицировать приложение, которому предназначены данные для отправки.

2- Простой пример с Socket

SimpleServerProgram.java
package org.o7planning.tutorial.socket;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SimpleServerProgram {

   public static void main(String args[]) {

       ServerSocket listener = null;
       String line;
       BufferedReader is;
       BufferedWriter os;
       Socket socketOfServer = null;

       // Try to open a server socket on port 9999
       // Note that we can't choose a port less than 1023 if we are not
       // privileged users (root)

 
       try {
           listener = new ServerSocket(9999);
       } catch (IOException e) {
           System.out.println(e);
           System.exit(1);
       }

       try {
           System.out.println("Server is waiting to accept user...");

           // Accept client connection request
           // Get new Socket at Server.    
           socketOfServer = listener.accept();
           System.out.println("Accept a client!");

           // Open input and output streams
           is = new BufferedReader(new InputStreamReader(socketOfServer.getInputStream()));
           os = new BufferedWriter(new OutputStreamWriter(socketOfServer.getOutputStream()));


           while (true) {
               // Read data to the server (sent from client).
               line = is.readLine();
               
               // Write to socket of Server
               // (Send to client)
               os.write(">> " + line);
               // End of line
               os.newLine();
               // Flush data.
               os.flush();  


               // If users send QUIT (To end conversation).
               if (line.equals("QUIT")) {
                   os.write(">> OK");
                   os.newLine();
                   os.flush();
                   break;
               }
           }

       } catch (IOException e) {
           System.out.println(e);
           e.printStackTrace();
       }
       System.out.println("Sever stopped!");
   }
}
SimpleClientDemo.java
package org.o7planning.tutorial.socket;

import java.io.*;
import java.net.*;

public class SimpleClientDemo {

   public static void main(String[] args) {

       // Server Host
       final String serverHost = "localhost";

       Socket socketOfClient = null;
       BufferedWriter os = null;
       BufferedReader is = null;

       try {
           
           // Send a request to connect to the server is listening
           // on machine 'localhost' port 9999.
           socketOfClient = new Socket(serverHost, 9999);

           // Create output stream at the client (to send data to the server)
           os = new BufferedWriter(new OutputStreamWriter(socketOfClient.getOutputStream()));


           // Input stream at Client (Receive data from the server).
           is = new BufferedReader(new InputStreamReader(socketOfClient.getInputStream()));

       } catch (UnknownHostException e) {
           System.err.println("Don't know about host " + serverHost);
           return;
       } catch (IOException e) {
           System.err.println("Couldn't get I/O for the connection to " + serverHost);
           return;
       }

       try {

           // Write data to the output stream of the Client Socket.
           os.write("HELO");
 
           // End of line
           os.newLine();
   
           // Flush data.
           os.flush();  
           os.write("I am Tom Cat");
           os.newLine();
           os.flush();
           os.write("QUIT");
           os.newLine();
           os.flush();


           
           // Read data sent from the server.
           // By reading the input stream of the Client Socket.
           String responseLine;
           while ((responseLine = is.readLine()) != null) {
               System.out.println("Server: " + responseLine);
               if (responseLine.indexOf("OK") != -1) {
                   break;
               }
           }

           os.close();
           is.close();
           socketOfClient.close();
       } catch (UnknownHostException e) {
           System.err.println("Trying to connect to unknown host: " + e);
       } catch (IOException e) {
           System.err.println("IOException:  " + e);
       }
   }

}

Запуск примера:

Для начала вам нужно запустить класс  SimpleServerProgram:
Затем запустить класс  SimpleClientDemo.

3- Пример Socket + Thread

Обычно создается соединение между серверной программой (Server) и 1 клиентом, вы должны позволить им говорить друг с другом в потоке (Thread), поэтому каждый раз при создании нового соединения, создается ноый поток.
ServerProgram.java
package org.o7planning.tutorial.socketthread;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerProgram {

   public static void main(String args[]) throws IOException {

       ServerSocket listener = null;

       System.out.println("Server is waiting to accept user...");
       int clientNumber = 0;

       // Try to open a server socket on port 7777
       // Note that we can't choose a port less than 1023 if we are not
       // privileged users (root)

       try {
           listener = new ServerSocket(7777);
       } catch (IOException e) {
           System.out.println(e);
           System.exit(1);
       }

       try {
           while (true) {
               // Accept client connection request
               // Get new Socket at Server.

               Socket socketOfServer = listener.accept();
               new ServiceThread(socketOfServer, clientNumber++).start();
           }
       } finally {
           listener.close();
       }

   }

   private static void log(String message) {
       System.out.println(message);
   }

   private static class ServiceThread extends Thread {

       private int clientNumber;
       private Socket socketOfServer;

       public ServiceThread(Socket socketOfServer, int clientNumber) {
           this.clientNumber = clientNumber;
           this.socketOfServer = socketOfServer;

           // Log
           log("New connection with client# " + this.clientNumber + " at " + socketOfServer);
       }

       @Override
       public void run() {

           try {

               // Open input and output streams
               BufferedReader is = new BufferedReader(new InputStreamReader(socketOfServer.getInputStream()));
               BufferedWriter os = new BufferedWriter(new OutputStreamWriter(socketOfServer.getOutputStream()));

               while (true) {
                   // Read data to the server (sent from client).
                   String line = is.readLine();
                   
                   // Write to socket of Server
                   // (Send to client)                    
                   os.write(">> " + line);
                   // End of line.
                   os.newLine();
                   // Flush data.
                   os.flush();

           
                   // If users send QUIT (To end conversation).
                   if (line.equals("QUIT")) {
                       os.write(">> OK");
                       os.newLine();
                       os.flush();
                       break;
                   }
               }

           } catch (IOException e) {
               System.out.println(e);
               e.printStackTrace();
           }
       }
   }
}
ClientDemo.java
package org.o7planning.tutorial.socketthread;

import java.io.*;
import java.net.*;
import java.util.Date;

public class ClientDemo {

   public static void main(String[] args) {

 
       final String serverHost = "localhost";

       Socket socketOfClient = null;
       BufferedWriter os = null;
       BufferedReader is = null;

       try {
     
           
           // Send a request to connect to the server is listening
           // on machine 'localhost' port 7777.            
           socketOfClient = new Socket(serverHost, 7777);
     
           // Create output stream at the client (to send data to the server)
           os = new BufferedWriter(new OutputStreamWriter(socketOfClient.getOutputStream()));

     
           // Input stream at Client (Receive data from the server).
           is = new BufferedReader(new InputStreamReader(socketOfClient.getInputStream()));

       } catch (UnknownHostException e) {
           System.err.println("Don't know about host " + serverHost);
           return;
       } catch (IOException e) {
           System.err.println("Couldn't get I/O for the connection to " + serverHost);
           return;
       }

       try {
   
           // Write data to the output stream of the Client Socket.
           os.write("HELO! now is " + new Date());
       
           // End of line
           os.newLine();
       
           // Flush data.
           os.flush();  
           os.write("I am Tom Cat");
           os.newLine();
           os.flush();
           os.write("QUIT");  
           os.newLine();
           os.flush();

     
           
           // Read data sent from the server.
           // By reading the input stream of the Client Socket.
           String responseLine;
           while ((responseLine = is.readLine()) != null) {
               System.out.println("Server: " + responseLine);
               if (responseLine.indexOf("OK") != -1) {
                   break;
               }
           }

           os.close();
           is.close();
           socketOfClient.close();
       } catch (UnknownHostException e) {
           System.err.println("Trying to connect to unknown host: " + e);
       } catch (IOException e) {
           System.err.println("IOException:  " + e);
       }
   }

}

View more categories: