第二次课:通信程序的改进

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第二次课:通信程序的改进相关的知识,希望对你有一定的参考价值。

第一部分:客户端

1、程序结构图

技术分享

2、创建一个用于读取消息的线程

package cn.shxy.net;

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

/**
 * 专门用于读取数据的线程类
 * 
 * @author John
 *
 */
public class ReadMessageThread extends Thread {
    //与服务器通信的套接字
    private Socket server;

    //构造函数
    public ReadMessageThread(Socket socket) {
        server = socket;
    }

    @Override
    public void run() {
        System.out.println("读取消息的线程已启动...");
        try {
            //获取输入流对象
            BufferedReader reader = new BufferedReader(new InputStreamReader(server.getInputStream()));
            //循环读取服务器发送的消息,循环条件是套接字没有关闭
            while (!server.isClosed()) {
                //读取一行消息
                String message = reader.readLine();
                //将消息显示出来
                System.out.println(server.getInetAddress() + ":" + server.getPort() + ":" + message);
                
                //如果是退出消息,则关闭套接字
                if (message.equalsIgnoreCase("quit")) {
                    server.close();
                    break;
                }
            }
        } catch (IOException e) {
        }
    }
}

3、修改主程序的代码,加上获取用户输入的循环

package cn.shxy.net;

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class TCPClient {
    //主函数
    public static void main(String[] args) throws UnknownHostException, IOException{
        new TCPClient();
    }
    
    //套接字
    private Socket server;
    
    //构造函数
    public TCPClient() throws UnknownHostException, IOException{
        //与服务器相连
        server = new Socket("127.0.0.1", 65535);
        
        ReadMessageThread readMessageThread = new ReadMessageThread(server);
        readMessageThread.start();

        PrintStream printer = new PrintStream(server.getOutputStream());
        
        @SuppressWarnings("resource")
        Scanner scanner = new Scanner(System.in);
        
        while(!server.isClosed()){
            String cmd = scanner.nextLine();
            printer.println(cmd);
            
            if(cmd.equalsIgnoreCase("quit")){
                server.close();
                break;
            }
        }
    }
}

第二部分:服务器端程序

1、结构图

技术分享

2、编写和客户端相同的用于读取消息的线程

package cn.shxy.net;

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

/**
 * 专门用于读取数据的线程类
 * @author John
 *
 */
public class ReadMessageThread extends Thread {
    private Socket client;
    
    public ReadMessageThread(Socket socket){
        client = socket;
    }
    
    @Override
    public void run(){
        System.out.println("读取消息的线程已启动...");
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            while(!client.isClosed()){
                String message = reader.readLine();
                System.out.println(client.getInetAddress() + ":" + client.getPort() + ":" + message);
                if(message.equalsIgnoreCase("quit")){
                    client.close();
                    break;
                }
            }
        } catch (IOException e) {
            
        }
    }
}

3、修改主程序,加上循环获取输入命令的语句

package cn.shxy.net;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class TCPServer {
    //主函数
    public static void main(String[] args) throws IOException{
        new TCPServer();
    }
    
    //服务器套接字
    private ServerSocket serverSocket;
    //客户端套接字
    private Socket client;
    
    //构造函数
    public TCPServer() throws IOException{
        //实例化服务器套接字
        serverSocket = new ServerSocket(65535);
        //接受客户端连接
        client = serverSocket.accept();
        
        //开启读取消息的线程
        ReadMessageThread readMessageThread = new ReadMessageThread(client);
        readMessageThread.start();
        
        //获取输出流对象
        PrintStream printer = new PrintStream(client.getOutputStream());
        //获取输入命令
        @SuppressWarnings("resource")
        Scanner scanner = new Scanner(System.in);
        
        //循环
        while(!client.isClosed()){
            //获取用户输入的命令
            String cmd = scanner.nextLine();
            //将命令发送给客户端
            printer.println(cmd);
            
            //如果是退出命令,则关闭套接字,结束程序
            if(cmd.equalsIgnoreCase("quit")){
                client.close();
                break;
            }
        }
        
    }
}

注意:运行程序时,应该先启动服务器端程序,后启动客户端程序!

以上是关于第二次课:通信程序的改进的主要内容,如果未能解决你的问题,请参考以下文章

四周第二次课

第二次课中的一些问题

一周第二次课(12月12日)NAT

一周第二次课(3月20日) 笔记

c #可视化程序设计(第二章第二次课)

二周第二次课(12月19日)