一、 TCP/IP协议(Transmission Control Protocol/Internet Protocol)传输控制协议/Internet协议,是通信领域的基础、核心协议,
其他的协议都是由TCP/IP派生出来的子协议,如:HTTP(Haper Text Transfer Protocol)超文本传输协议、FTP(File Transfer Protocol)文件传输协议。
二、 Java语言的网络开发:
在Java中通过Socket(套接字,是通信的通道)来实现TCP/IP协议的规范,实现网络通信,具体会涉及到两个类和两个方法:
- ServerSocket实现类:在创建对象时设置服务器在哪个端口监听客服端的连接。
- Socket实现类:在创建对象时设置要去连接哪个“主机”的哪个“端口”与服务器建立连接。
getInputStream()方法:用于获取对方发送的数据的通道。
getOutputStream()方法:用于向对方发送数据的通道。
三、 Socket网络编程的开发流程:
- 服务器端的开发流程:
1) 创建ServerSocket的对象,同时指定在哪个端口监听客户端的连接。
2) 再通过ServerSocket的对象调用accept()方法获取Socket,通过Socket通道可以获取对方发送的信息,同时也可以向对方发送消息。
3) 通过socket调用getInputStream()方法或getOutputStream()方法建立“输入”、“输出”的通道实现获取或发送消息,
为了提高效率,可以将发送过程中使用的字节流转化为字符流,且可以将字符流放置到带缓冲的字符流中。
4) 在循环中反复向“文本域jTextArea”追加对方发送过来的消息。
5) 针对“发送按钮 jButton”调用addActionListener方法进行监听他是否被点击,点击时要完成:1、向对方发送消息。2、将消息追加到文本域
6) 关闭打开的资源:ServerSocket、Socket、InputStreamReader、BufferedInputStream、PrintWriter
package com.oop.ch15; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; 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 javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * 聊天程序:服务器端 */ public class QQServer { static JTextArea jTextArea = null; // 文本域: 显示信息的地方 static JScrollPane jScrollPane = null; // 屏幕滚动条: 当文本域内容较多时显示滚动条 static JTextField jTextField = null; // 文本框:用户输入信息的地方 static JButton jButton = null; // 按扭: 发送按扭 static JPanel jPanel = null; // 面板: 放置元素的场所 static PrintWriter printWriter = null; // 发送信息:将信息发送到对方的对象 static String toStr = null; // 发送到客户端的信息,用于判断是否发送结束的标志 static String getStr = null; // 保存对方发送过来的消息 public static void main(String[] args) { /** 一、显示“聊天对话框”界面 开始 */ JFrame jFrame = new JFrame("聊天对话框(服务器端)"); // 创建一个面板 jPanel = new JPanel(); // 创建一个文本域, 并将其放入滚动窗格组件(JScrollPane)中实现滚动条的效果。 jTextArea = new JTextArea(); jScrollPane = new JScrollPane(jTextArea); // 创建一个文本框 jTextField = new JTextField(20); // 创建一个发送按扭 jButton = new JButton("发送"); /* 4. 对发送按扭进行监听 */ /* * 5) 针对“发送按钮 jButton”调用addActionListener()方法进行监听他是否被点击, * 点击时要完成:a、向对方发送消息。b、将消息追加到文本域 */ jButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //获取输入框中的消息,并将消息前后空格去掉 toStr = jTextField.getText().trim(); //判断如果监听到的事件是jButton就执行下面的操作 if (e.getSource() == jButton) { //如果不为空 if (toStr != null && toStr != "") { //把输入框中的消息给printWriter,然后终止该行。 printWriter.println(toStr); //在文本域中追加消息 jTextArea.append("服务器端:" + toStr + " "); //将输入框置空 jTextField.setText(""); //如果自己发送的消息或者收到的消息是88就结束聊天 if ("88".equals(toStr) || "88".equals(getStr)) { System.out.println("结束聊天"); return; } } } } }); // 文本框、发送按扭放置到面板中JPanel jPanel.add(jTextField); jPanel.add(jButton); // 将带滚动的文本域、面板放置到窗体中 jFrame.add(jScrollPane, "Center"); jFrame.add(jPanel, BorderLayout.SOUTH); // 将QQ图片放置在窗体的左上角。 jFrame.setIconImage((new ImageIcon("G:/Javatest/qq.jpg")).getImage()); jFrame.setBounds(100, 100, 400, 300); // 设置窗体初始位置、大小 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗体时退出程序 jFrame.setVisible(true); // 将窗体设置为可见的 /** 一、显示“聊天对话框”界面 结束 */ /** 二、socket网络编程 开始 */ //将需要用到的资源定义在try外面,方便后面关闭这些资源 ServerSocket serverSocket = null; Socket socket = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; try { // 1) 创建ServerSocket的对象,同时指定在10000端口监听客户端的连接。 serverSocket = new ServerSocket(10000); /* * 2) 再通过ServerSocket的对象调用accept()方法获取Socket, * 通过Socket通道可以获取对方发送的信息,同时也可以向对方发送消息。 */ socket = serverSocket.accept(); /* * 3) 通过socket调用getInputStream()方法或getOutputStream()方法 , * 建立“输入”、“输出”的通道实现获取或发送消息, * 为了提高效率,可以将发送过程中使用的字节流转化为字符流, 且可以将字符流放置到带缓冲的字符流中。 */ inputStreamReader = new InputStreamReader(socket.getInputStream()); // 将传入的字节流转化为字符流 bufferedReader = new BufferedReader(inputStreamReader); // 将字符流放置到缓冲中 //向文本输出流打印对象的格式化表示形式。 printWriter = new PrintWriter(socket.getOutputStream(), true); // true表示立即发送 /* 4) 在循环中反复向“文本域jTextArea”追加对方发送过来的消息。 */ while (true) { //将从缓冲流中读取到的数据赋给getStr getStr = bufferedReader.readLine(); //在文本域中追加 jTextArea.append("客户端:" + getStr + " "); //判断是否结束聊天 if ("88".equals(getStr) || "88".equals(toStr)) { System.out.println("结束聊天"); break; } } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源 /* * 6) 关闭打开的资源:ServerSocket、Socket、InputStreamReader、 * BufferedInputStream、PrintWriter */ try { if (printWriter != null) { printWriter.close(); } if (bufferedReader != null) { bufferedReader.close(); } if (inputStreamReader != null) { inputStreamReader.close(); } if (socket != null) { socket.close(); } if (serverSocket != null) { serverSocket.close(); } } catch (IOException e) { e.printStackTrace(); } } /** 二、socket网络编程 结束 */ } }
- 客户端的开发流程:
1) 创建Socket的对象,new Socket(),指定客户端要连接哪台服务器的哪个端口,通过Socket通道可以获取对方发送的信息,同时也可以向对方发送消息。
2) 通过socket调用getInputStream()方法或getOutputStream()方法建立“输入”、“输出”的通道实现获取或发送消息,
为了提高效率,可以将发送过程中使用的字节流转化为字符流,且可以将字符流放置到带缓冲的字符流中。
3) 在循环中反复向“文本域jTextArea”追加对方发送过来的消息。
4) 针对“发送按钮 jButton”调用addActionListener方法进行监听他是否被点击,点击时要完成:a、向对方发送消息。B、将消息追加到文本域。
5) 关闭打开的资源:ServerSocket、Socket、InputStreamReader、BufferedInputStream、PrintWriter
package com.oop.ch15; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; /** * 聊天程序:客户端 */ public class QQClient { static JTextArea jTextArea = null; // 文本域: 显示信息的地方 static JScrollPane jScrollPane = null; // 屏幕滚动条: 当文本域内容较多时显示滚动条 static JTextField jTextField = null; // 文本框:用户输入信息的地方 static JButton jButton = null; // 按扭: 发送按扭 static JPanel jPanel = null; // 面板: 放置元素的场所 static PrintWriter printWriter = null; // 发送信息:将信息发送到对方的对象 static String toStr = null; // 发送到客户端的信息,用于判断是否发送结束的标志 static String getStr = null; // 保存对方发送过来的消息 public static void main(String[] args) { /** 一、显示“聊天对话框”界面 开始 */ JFrame jFrame = new JFrame("聊天对话框(客户端)"); // 创建一个面板 jPanel = new JPanel(); // 创建一个文本域, 并将其放入滚动窗格组件(JScrollPane)中实现滚动条的效果。 jTextArea = new JTextArea(); jScrollPane = new JScrollPane(jTextArea); // 创建一个文本框 jTextField = new JTextField(20); // 创建一个发送按扭 jButton = new JButton("发送"); /* 4. 对发送按扭进行监听 */ /* * 4) 针对“发送按钮 jButton”调用addActionListener()方法进行监听他是否被点击, * 点击时要完成:a、向对方发送消息。B、将消息追加到文本域 */ jButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //获取输入框中的消息,并将消息前后空格去掉 toStr = jTextField.getText().trim(); //判断如果监听到的事件是jButton就执行下面的操作 if (jButton == e.getSource()) { if (toStr != null && toStr != "") { printWriter.println(toStr); jTextArea.append("客户端:" + toStr + " "); jTextField.setText(""); if ("88".equals(toStr) || "88".equals(getStr)) { System.out.println("结束聊天"); return; } } } } }); // 文本框、发送按扭放置到面板中JPanel jPanel.add(jTextField); jPanel.add(jButton); // 将带滚动的文本域、面板放置到窗体中 jFrame.add(jScrollPane, "Center"); jFrame.add(jPanel, BorderLayout.SOUTH); // 将QQ图片放置在窗体的左上角。 jFrame.setIconImage((new ImageIcon("G:/Javatest/qq.jpg")).getImage()); jFrame.setBounds(500, 100, 400, 300); // 设置窗体初始位置、大小 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭窗体时退出程序 jFrame.setVisible(true); // 将窗体设置为可见的 /** 一、显示“聊天对话框”界面 结束 */ /** 二、socket网络编程 开始 */ //将需要用到的资源定义在try外面,方便后面关闭这些资源 Socket socket = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; try { /* * 1) 创建Socket的对象,new Socket(),指定客户端要连接哪台服务器的哪个端口, * 通过Socket通道可以获取对方发送的信息,同时也可以向对方发送消息。 */ //指定客户端要连接的服务器和服务器的端口 socket = new Socket("localhost", 10000); /* * 2) 通过socket调用getInputStream()方法或getOutputStream()方法 , * 建立“输入”、“输出”的通道实现获取或发送消息, * 为了提高效率,可以将发送过程中使用的字节流转化为字符流, 且可以将字符流放置到带缓冲的字符流中。 */ //接收:对接收到的数据进行操作 inputStreamReader = new InputStreamReader(socket.getInputStream()); // 将传入的字节流转化为字符流 bufferedReader = new BufferedReader(inputStreamReader); // 将字符流放置到缓冲中 //发送 printWriter = new PrintWriter(socket.getOutputStream(), true); /* 3) 在循环中反复向“文本域jTextArea”追加对方发送过来的消息。 */ while (true) { getStr = bufferedReader.readLine(); jTextArea.append("服务器端: " + getStr + " "); if ("88".equals(getStr) || "88".equals(toStr)) { System.out.println("结束聊天"); break; } } } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源 /* * 5) 关闭打开的资源:ServerSocket、Socket、InputStreamReader、 * BufferedInputStream、PrintWriter */ try { if (printWriter != null) { printWriter.close(); } if (bufferedReader != null) { bufferedReader.close(); } if (inputStreamReader != null) { inputStreamReader.close(); } if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } /** 二、socket网络编程 结束 */ } }