* Пример за приложения използващи сокети

Публикувано на 31 октомври 2011 в раздел ПИК-3 Java.

В представеното приложение е реализирана възможно най-базовата комуникация между клиент и сървър, при която се разменят поредица от текстови съобщения. Обърнете внимание, че не се използват нишки, т.е. за една “сесия” сървърът може да комуникира само с един клиент.

Server.java:

import java.io.PrintWriter;
import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Scanner;

public class Server{
  public static void main(String args[]) {
    ServerSocket serverSocket = null;
    Socket connection = null;
    Scanner socketIn = null;
    PrintWriter socketOut = null;
    int port = 1234;

    // Безкраен цикъл - сървъра ще приема връзки
    // докато програмата не бъде спряна принудително
    while(true){
      try {
        serverSocket = new ServerSocket(port);
        System.out.println("Сървъра очаква свързване...");
        connection = serverSocket.accept();
        System.out.println("Свърза се клиент:"
              +connection.getInetAddress().getHostName()
        );

        System.out.println("Подавам съобщение на клиента...");
        socketOut = new PrintWriter(connection.getOutputStream(), true);
        socketOut.println("Възможните команди са \"hi\" и \"exit\"");

        System.out.println("Сървъра очаква подаване на команда...");
        socketIn = new Scanner(new BufferedReader(
                          new InputStreamReader(connection.getInputStream()))
                       );

        String command = null;
        loop: do{
          socketOut.flush();
          command = socketIn.nextLine();
          switch(command){
            case "hi":
              System.out.println("Клиентът подаде команда \"hi\"");
              socketOut.println("OK");
              break;
            case "exit":
              System.out.println("Клиентът подаде команда \"exit\"");
              socketOut.println("OK");
              break loop;
            default:
              System.out.println("Получих непозната команда");
              socketOut.println("Не познавам тази команда");
              break;
          }
        }
        while(!command.equalsIgnoreCase("exit"));
        System.out.println("Затварям връзката с "
                             +connection.getInetAddress().getHostName()
                          );
      }
      catch(IOException e) {
        e.printStackTrace();
      }
      finally{
        try{
          if (socketIn!=null) socketIn.close();
          if (socketOut!=null) socketOut.close();
          if (connection!=null) connection.close();
          if (serverSocket!=null) serverSocket.close();
        }
        catch(IOException e){
          System.err.println("Не може да бъде затворен сокет");
        }
      }
    }
  }
}

 

Client.java:

import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.net.Socket;
import java.io.IOException;
import java.net.ConnectException;

public class Client{
   public static void main(String args[]){
     Socket connection = null;
     Scanner socketIn = null;
     PrintWriter socketOut = null;
     Scanner keyboardIn = new Scanner(System.in);
     int port = 1234;
     String host = "localhost";

     try{
       System.out.println("Очаквам свързване със сървъра");
       try{
         connection = new Socket(host, port);
       }
       catch(ConnectException e){
         System.err.println("Не мога да осъществя връзка със сървъра");
         return;
       }
       System.out.println("Свързването със сървъра беше успешно!");

       System.out.println("Приемам първоначално съобщение от сървъра...");
       socketIn = new Scanner(new BufferedReader(
                         new InputStreamReader(connection.getInputStream()))
                      );
       System.out.println("Съобщението е: "+socketIn.nextLine());

       String command = null;
       socketOut = new PrintWriter(connection.getOutputStream(), true);
       do{
         socketOut.flush();
         System.out.print("Въведете команда: ");
         command = keyboardIn.nextLine();
         socketOut.println(command.toLowerCase());

         System.out.println("Изчакване на отговор от сървъра...");
         String answer = socketIn.nextLine();
         System.out.println("Сървърът отговори: "+answer);
       }
       while (!command.equalsIgnoreCase("exit"));
       System.out.println("Затваряне на връзката...");

     }
     catch(IOException e) {
       e.printStackTrace();
     }
     finally{
       try{
         if(socketIn!=null) socketIn.close();
         if(socketOut!=null) socketOut.close();
         if(connection!=null) connection.close();
       }
       catch(IOException e){
         System.err.println("Не може да се затвори сокета");
       }
     }
   }
}



11 коментара за “Пример за приложения използващи сокети”


  1. Десислав Андреев:

    Само че не знам дали switch ще работи, тъй като Еклипс ми иска int или enum, a ние подаваме String


  2. Филип Петров:

    В Java SE 7 работи. Свалете си и използвайте JDK7. Не би трябвало да има значение дали средата е Eclipse или друга.

    За повече информация: http://download.oracle.com/javase/7/docs/technotes/guides/language/strings-switch.html


  3. Rooney:

    socketIn = new Scanner(new BufferedReader(
    new InputStreamReader(connection.getInputStream()))
    );

    на този ред(от Сървър класа) ми дава грешка


  4. Филип Петров:

    А на мен не.

    П.П. Ако има нужда от помощ, то е редно да се напишат поне малко подробности:

    1. Коя версия на JDK се използва?
    2. Каква е грешката?


  5. Rooney:

    JDK 1.7, а среедата е Eclipse.
    Грешката която дава е:

    - The constructor Scanner(BufferedReader) is undefined
    - BufferedReader cannot be resolved to a type
    - InputStreamReader cannot be resolved to a type


  6. Филип Петров:

    Определено има нещо нередно в твоята инсталация. Тази конструкция е съвсем валидна. Scanner си има конструктор приемащ “InputStream” като вход. Виж дали ще можеш да компилираш това:

    http://www.java2s.com/Code/Java/File-Input-Output/newScannernewBufferedReadernewFileReaderxanadutxt.htm


  7. Rooney:

    Сега се оправи като го написах наново. Явно средата не и е било до тези обекти одеве.


  8. Десислав Андреев:

    При мен, обаче, не се получава. Макар и да казвам на Еклипс, че трябва да рънва двата файла с 1.7 (дори и на програмата с комплексните числа), не се получава. Не приема в switch да имам String


  9. Филип Петров:

    Проблемът е очевидно в Eclipse. Ето тук са писали за проблема:

    http://stackoverflow.com/questions/6231907/java-7-switch-statement-with-strings-not-working

    Винаги е така с новостите – трудно се внедряват.


  10. stan:

    Не се казва “насилствено”, “принудително”. Всяко нещо трябва да се назовава точно.


  11. Филип Петров:

    Благодаря, ще коригирам.


Trackback URI | RSS за коментарите

Пусни коментар