Java的Socket编程实例

socket简介

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。

代码解释

Socket编程可以使用 TCP协议,也可以使用UDP协议,我这里使用的是TCP协议的代码,运行的时候先运行服务器端,再运行客户端。

服务端

package org.somken.test;

 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.Calendar;

 /**
 * 服务器端
 *author 周谦
*/
 public class SocketSServer {  
     public static void main(String[] args) throws IOException {  
         System.out.println("服务器开始运行...\n");  

       //创建侦听传入连接的服务器套接字
        //端口10000上的请求。 
        ServerSocket server = new ServerSocket(10000);  

         while (true) {  

            //侦听来自客户端的传入连接请求
            //programs,建立连接,返回socket
            //表示此连接的对象。
             Socket s = server.accept();  
             System.out.println("接受连接中...\n");  

           //启动一个线程来处理连接。  
            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 {  
                //创建一个链接到套接字的输入流读取器
                //面向字节的输入流。输入流读取器
                //将从套接字读取的字节转换为字符。这个
                //转换基于平台的默认字符
                //设置。
                  InputStreamReader isr;  
                  isr = new InputStreamReader(s.getInputStream());  

                  //创建一个链接到输入流的缓冲读取器  
                  br = new BufferedReader(isr);  

                  /*创建一个链接到套接字面向字节的输出流的打印写入程序。打印作者创建
                    将发送到套接字的字符转换为字节的中间输出流编写器。转换
                    基于平台的默认字符集。  
                    */
                  pw = new PrintWriter(s.getOutputStream(), true);  

                  //创建可以获取日期和时间信息的日历。 
                  Calendar c = Calendar.getInstance();  

                  do {  
                      //获取客户端程序的下一个命令。  
                      String cmd = br.readLine();  

                      // 如果客户端程序已关闭其输出流,则退出。 
                      if (cmd == null)  
                          break;  

                      //将命令转换为大写,以便于比较。
                      cmd = cmd.toUpperCase();  

                      // 如果客户端程序发送bye命令,则终止。 
                      if (cmd.startsWith("BYE"))  
                          break;  

                      // 如果客户端程序发送日期或时间命令,则将当前日期/时间返回给客户端程序。
                      if (cmd.startsWith("DATE") || cmd.startsWith("TIME"))  
                          pw.println(c.getTime().toString());  

                      //如果客户端程序发送dom(月日)命令,则将当前月日返回给客户端程序。 
                      if (cmd.startsWith("DOM"))  
                          pw.println("" + c.get(Calendar.DAY_OF_MONTH));  

                      // 如果客户端程序发送dow(星期几)命令,
                      //则将当前工作日(作为字符串)返回给客户端程序。
                      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");  
                          }  

                      // 如果客户端程序发送doy(一年中的某一天)命令,则将当前的一年中的某一天返回给客户端程序 
                      if (cmd.startsWith("DOY"))  
                          pw.println("" + c.get(Calendar.DAY_OF_YEAR));  

                      //  如果客户端程序发送暂停命令,则睡眠3秒钟。
                      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("关闭连接...\n");  
                  try {  
                      if (br != null)  
                          br.close();  

                      if (pw != null)  
                          pw.close();  

                      if (s != null)  
                          s.close();  
                  } catch (IOException e) {  
                  }  
              }  
          }  
      }  

客户端代码

package org.somken.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

/**
 author 周谦
*/
 public class SocketSClient {  
     public static void main(String[] args) {  
         String host = "localhost";  

         // 如果用户指定命令行参数,则该参数表示主机名。  
         if (args.length == 1)  
            host = args[0];  

        BufferedReader br = null;  
        PrintWriter pw = null;  
         Socket s = null;  

        try {  
             //创建一个套接字,尝试连接到位于端口10000的主机上的服务器程序。  
             s = new Socket(host, 10000);  

             InputStreamReader isr;  
             isr = new InputStreamReader(s.getInputStream());  

             br = new BufferedReader(isr);   
             pw = new PrintWriter(s.getOutputStream(), true);  

             // 向服务器发送日期命令。
             pw.println("DATE");  

             // 获取并打印当前日期/时间。
             System.out.println(br.readLine());  

             // 向服务器发送暂停命令。这允许多个客户端启动并验证服务器是否正在生成多个线程。
             pw.println("PAUSE");  
             // 向服务器发送dow命令。

             pw.println("DOW");  

             // 获取并打印当前星期几。
            System.out.println(br.readLine());  

             // 将dom命令发送到服务器。
             pw.println("DOM");  

             // 获取并打印当前月份的日期。
             System.out.println(br.readLine());  

             // 将doy命令发送到服务器。
            pw.println("DOY");  

             // 获取并打印当前日期。
             System.out.println(br.readLine());  
        } catch (IOException e) {  
             System.out.println(e.toString());  
         } finally {  
            try {  
                 if (br != null)  
                    br.close();  
                if (pw != null)  
                    pw.close();  
                 if (s != null)  
                     s.close();  
            } catch (IOException e) {  
             }  
         }  
     }  
 }  

发表评论

邮箱地址不会被公开。 必填项已用*标注