第四次过程性考核

 

码云地址:https://gitee.com/snjsnjsnj/events

心得:

1:Socket的传输模式

Socket有两种主要的操作方式:面向连接的和无连接的。(TCP/UDP)

  面向连接的Socket操作就像一部电话,Socket必须在发送数据之前与目的地的Socket取得连接,一旦连接建立了,Socket就可以使用一个流接口进行打开、读写以及关闭操作。并且,所有发送的数据在另一端都会以相同的顺序被接收。

  无连接的Socket操作就像一个邮件投递,每一个数据报都是一个独立的单元,它包含了这次投递的所有信息(目的地址和要发送的内容)。在这个模式下的Socket不需要连接目的地Socket,它只是简单的投出数据报。

  由此可见,无连接的操作是快速高效的,但是数据安全性不佳;面向连接的操作效率较低,但数据的安全性较好。

  本文主要介绍的是面向连接的Socket操作:

2:

Socket的构造方法

  Java在包java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的Socket客户端和服务器端。

  Socket的构造方法如下:

  (1)Socket(InetAddress address, int port);

  (2)Socket(InetAddress address, int port, boolean stream);

  (3)Socket(String host, int port);

  (4)Socket(String host, int port, boolean stream);

  (5)Socket(SocketImpl impl);

  (6)Socket(String host, int port, InetAddress localAddr, int localPort);

  (7)Socket(InetAddress address, int port, InetAddrss localAddr, int localPort);

  ServerSocket的构造方法如下:

  (1)ServerSocket(int port);

  (2)ServerSocket(int port, int backlog);

  (3)ServerSocket(int port, int backlog, InetAddress bindAddr);

服务器端创建了一个ServerSocket:
 try {
  ServerSocket serverSocket = new ServerSocket(50000); //创建一个ServerSocket,用于监听客户端Socket的连接请求
   while(true) {
   Socket socket = serverSocket.accept();     //每当接收到客户端的Socket请求,服务器端也相应的创建一个Socket
      //todo开始进行Socket通信
   }catch (IOException e) {
   e.printStackTrace();
   }
客户端创建并启动一个Socket:
 try {
   socket = new Socket("192.168.1.101", 50000); //192.168.1.101是服务器的IP地址,50000是端口号
    //todo开始进行Socket通信
  } catch (IOException e) {
   e.printStackTrace();
}
服务器端ServerSocket的实现:
/*
   * Class : MyServer类,用于监听客户端Socket连接请求
   * Author : 博客园-snj流沙
   */
  public class MyServer {
  
   //定义ServerSocket的端口号
   private static final int SOCKET_PORT = 50000;
   //使用ArrayList存储所有的Socket
   public static ArrayList<Socket> socketList = new ArrayList<Socket>();
  
   public void initMyServer() {
   try {
        //创建一个ServerSocket,用于监听客户端Socket的连接请求
   ServerSocket serverSocket = new ServerSocket(SOCKET_PORT);
   while(true) {
   //每当接收到客户端的Socket请求,服务器端也相应的创建一个Socket
   Socket socket = serverSocket.accept();
   socketList.add(socket);
   //每连接一个客户端,启动一个ServerThread线程为该客户端服务
   new Thread(new ServerThread(socket)).start();
   }
   }catch (IOException e) {
   e.printStackTrace();
   }
   }

   public static void main(String[] args) {
   MyServer myServer = new MyServer();
   myServer.initMyServer();
   }
  }
ServerThread类的具体实现如下:
public class ServerThread implements Runnable {
  
   //定义当前线程所处理的Socket
   private Socket socket = null;
   //该线程所处理的Socket对应的输入流
   private BufferedReader bufferedReader = null;
  
   /*
   * Function : ServerThread的构造方法
   * Author : 博客园-snj流沙
   */
   public ServerThread(Socket socket) throws IOException {
   this.socket = socket;
   //获取该socket对应的输入流
   bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
   }
  
   /*
   * Function : 实现run()方法,将读到的客户端内容进行广播
   * Author : 博客园-snj流沙
   */
   public void run() {
   try {
   String content = null;
   //采用循环不断地从Socket中读取客户端发送过来的数据
   while((content = bufferedReader.readLine()) != null) {
   //将读到的内容向每个Socket发送一次
   for(Socket socket : MyServer.socketList) {
   //获取该socket对应的输出流
   PrintStream printStream = new PrintStream(socket.getOutputStream());
   //向该输出流中写入要广播的内容
   printStream.println(packMessage(content));
  
   }
   e.printStackTrace();
   }
   }
  
   /*
   * Function : 对要广播的数据进行包装
   * Author : 博客园-snj流沙
   */
   private String packMessage(String content) {
   String result = null;
   SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"); //设置日期格式
   if(content.startsWith("USER_ONE")) {
   String message = content.substring(8); //获取用户发送的真实的信息
   result = "\n" + "往事如风 " + df.format(new Date()) + "\n" + message;
   }
   if(content.startsWith("USER_TWO")) {
   String message = content.substring(8); //获取用户发送的真实的信息
   result = "\n" + "依旧淡然 " + df.format(new Date()) + "\n" + message;
   }
   return result;
   }
  
  }
客户端Socket的实现:
/*
* Function : 初始化Socket
* Author : 博客园-snj流沙
*/
private void initSocket() {
try {
socketUser1 = new Socket(URL_PATH, SOCKET_PORT); //用户1的客户端Socket
socketUser2 = new Socket(URL_PATH, SOCKET_PORT); //用户2的客户端Socket
clientThread = new ClientThread(); //客户端启动ClientThread线程,读取来自服务器的数据
clientThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
ClientThread的具体实现:
/*
* Function : run()方法,用于读取来自服务器的数据
* Author : 博客园-snj流沙
*/
  public void run() {
  try {
   String content = null;
   while((content = bufferedReader .readLine()) != null) {
   Bundle bundle = new Bundle();
   bundle.putString(KEY_CONTENT, content);
   Message msg = new Message();
   msg.setData(bundle); //将数据封装到Message对象中
   myHandler.sendMessage(msg);
   }
   } catch (Exception e) {
   e.printStackTrace();
   }
  }
创建一个内部类MyHandler,让它继承Handler类,并实现handleMessage()方法:
/*
* Class : 内部类MyHandler,用于接收消息并处理
* Author : 博客园-snj流沙
*/
private class MyHandler extends Handler {
public void handleMessage(Message msg) {
Bundle bundle = msg.getData(); //获取Message中发送过来的数据
String content = bundle.getString(KEY_CONTENT);
MyContent.setContent(content); //保存聊天记录
mTextView.setText(MyContent.getContent());
}
}

 

posted @ 2018-12-13 14:29  snjsnj  阅读(160)  评论(2)    收藏  举报