Java网络编程基本(四) ServerSocket类利用
当前位置:以往代写 > JAVA 教程 >Java网络编程基本(四) ServerSocket类利用
2019-06-14

Java网络编程基本(四) ServerSocket类利用

Java网络编程基本(四) ServerSocket类利用

副标题#e#

由于SSClient利用了流套接字,所以处事措施也要利用流套接字。

这就要建设一个ServerSocket工具,ServerSocket有几个结构函数,最简朴的是ServerSocket(int port),当利用ServerSocket(int port)建设一个ServerSocket工具,port参数通报端标语,这个端口就是处事器监听毗连请求的端口,假如在这时呈现错误将抛出IOException异常工具,不然将建设ServerSocket工具并开始筹备吸收毗连请求。

接下来处事措施进入无限轮回之中,无限轮回从挪用ServerSocket的accept()要领开始,在挪用开始后accept()要领将导致挪用线程阻塞直到毗连成立。在成立毗连后accept()返回一个最近建设的Socket工具,该Socket工具绑定了客户措施的IP地点或端标语。

由于存在单个处事措施与多个客户措施通讯的大概,所以处事措施响应客户措施不该该花许多时间,不然客户措施在得随处事前有大概花许多时间来期待通讯的成立,然而处事措施和客户措施的会话有大概是很长的(这与电话雷同),因此为加速对客户措施毗连请求的响应,典范的要领是处事器主机运行一个靠山线程,这个靠山线程处理惩罚处事措施和客户措施的通讯。

为了示范我们在上面谈到的慨念并完成SSClient措施,下面我们建设一个SSServer措施,措施将建设一个ServerSocket工具来监听端口10000的毗连请求,假如乐成处事措施将期待毗连输入,开始一个线程处理惩罚毗连,并响应来自客户措施的呼吁。下面就是这段措施的代码:

Listing 3: SSServer.java

// SSServer.java
import java.io.*;
import java.net.*;
import java.util.*;
class SSServer
{
  public static void main (String [] args) throws IOException
  { 
   System.out.println ("Server starting...\n");
   // Create a server socket that listens for incoming connection
   // requests on port 10000.
   ServerSocket server = new ServerSocket (10000);
   while (true)
   {
    // Listen for incoming connection requests from client
    // programs, establish a connection, and return a Socket
    // object that redivsents this connection.
    Socket s = server.accept ();
    System.out.println ("Accepting Connection...\n");
    // Start a thread to handle the connection.
    new ServerThread (s).start ();
   }
  }
}
class ServerThread extends Thread
{
  private Socket s;
  ServerThread (Socket s)
  {
   this.s = s;
  }
  public void run ()
  {
   BufferedReader br = null;
   PrintWriter pw = null;
   try
   {
    // Create an input stream reader that chains to the socket's
    // byte-oriented input stream. The input stream reader
    // converts bytes read from the socket to characters. The
    // conversion is based on the platform's default character
    // set.
    InputStreamReader isr;
    isr = new InputStreamReader (s.getInputStream ());
    // Create a buffered reader that chains to the input stream
    // reader. The buffered reader supplies a convenient method
    // for reading entire lines of text.
    br = new BufferedReader (isr);
    // Create a print writer that chains to the socket's byte-
    // oriented output stream. The print writer creates an
    // intermediate output stream writer that converts
    // characters sent to the socket to bytes. The conversion
    // is based on the platform's default character set.
    pw = new PrintWriter (s.getOutputStream (), true);
    // Create a calendar that makes it possible to obtain date
    // and time information.
    Calendar c = Calendar.getInstance ();
  // Because the client program may send multiple commands, a
    // loop is required. Keep looping until the client either
    // explicitly requests termination by sending a command
    // beginning with letters BYE or implicitly requests
    // termination by closing its output stream.
    do
    {
     // Obtain the client program's next command.
     String cmd = br.readLine ();
     // Exit if client program has closed its output stream.
     if (cmd == null)
      break;
     // Convert command to uppercase, for ease of comparison.
     cmd = cmd.toUpperCase ();
     // If client program sends BYE command, terminate.
     if (cmd.startsWith ("BYE"))
      break;
     // If client program sends DATE or TIME command, return
     // current date/time to the client program.
     if (cmd.startsWith ("DATE") || cmd.startsWith ("TIME"))
      pw.println (c.getTime ().toString ());
     // If client program sends DOM (Day Of Month) command,
     // return current day of month to the client program.
     if (cmd.startsWith ("DOM"))
      pw.println ("" + c.get (Calendar.DAY_OF_MONTH));
     // If client program sends DOW (Day Of Week) command,
     // return current weekday (as a string) to the client
     // program.
     if (cmd.startsWith ("DOW"))
      switch (c.get (Calendar.DAY_OF_WEEK))
  {
      case Calendar.SUNDAY : pw.println ("SUNDAY");
       break;
      case Calendar.MONDAY : pw.println ("MONDAY");
       break;
      case Calendar.TUESDAY : pw.println ("TUESDAY");
       break;
      case Calendar.WEDNESDAY: pw.println ("WEDNESDAY");
       break;
      case Calendar.THURSDAY : pw.println ("THURSDAY");
       break;
      case Calendar.FRIDAY : pw.println ("FRIDAY");
       break;
      case Calendar.SATURDAY : pw.println ("SATURDAY");
     }
     // If client program sends DOY (Day of Year) command,
     // return current day of year to the client program.
     if (cmd.startsWith ("DOY"))
      pw.println ("" + c.get (Calendar.DAY_OF_YEAR));
      // If client program sends PAUSE command, sleep for three
      // seconds.
     if (cmd.startsWith ("PAUSE"))
     try
     {
      Thread.sleep (3000);
     }
     catch (InterruptedException e)
     {
     }
    }
    while (true);
    {
    catch (IOException e)
    {
        System.out.println (e.toString ());
    }
    finally
    {
     System.out.println ("Closing Connection...\n");
     try
     {
      if (br != null)
       br.close ();
       if (pw != null)
        pw.close ();
       if (s != null)
        s.close ();
     }
     catch (IOException e)
     {
     }
    }
   }
}


#p#副标题#e#

运行这段措施将获得下面的输出:

Server starting...
Accepting Connection...
Closing Connection...

#p#分页标题#e#

SSServer的源代码声明白一对类:SSServer 和ServerThread;SSServer的main()要领建设了一个ServerSocket工具来监听端口10000上的毗连请求,假如乐成, SSServer进入一个无限轮回中,瓜代挪用ServerSocket的 accept() 要领来期待毗连请求,同时启动靠山线程处理惩罚毗连(accept()返回的请求)。线程由ServerThread担任的start()要领开始,并执行ServerThread的run()要领中的代码。

一旦run()要领运行,线程将建设BufferedReader, PrintWriter和 Calendar工具并进入一个轮回,这个轮回由读(通过BufferedReader的 readLine())来自客户措施的一行文本开始,文本(呼吁)存储在cmd引用的string工具中,假如客户措施过早的封锁输出流,会产生什么呢?谜底是:cmd将得不到赋值。

留意必需思量到这种环境:在处事措施正在读输入流时,客户措施封锁了输出流,假如没有对这种环境举办处理惩罚,那么措施将发生异常。

一旦编译了SSServer的源代码,通过输入Java SSServer来运行措施,在开始运行SSServer后,就可以运行一个或多个SSClient措施。

    关键字:

在线提交作业