Javaweb--实验三TCP网络编程--期末复盘

实验3 TCP网络编程

需要详细文档资料见文章末尾

一、实验目的:

1、熟悉TCP网络编程的一般操作。
2、理解多线程的作用。
3、理解ArrayList集合类的作用。
4、理解事件处理机制。
5、了解swing编程。

二、 实验内容:

1、通过TCP网络编程实现:每次运行客户端,都能够从服务器中获得不同的诗歌的名字。请在【代码一】~【代码五】填写代码。

(1)新建名为”ex3”的项目(Java应用程序)。在项目中,新建Java类,命名为“DailyPoetryClient”。在DailyPoetryClient.java文件中,定义客户端类。客户端类的主要功能:打印输出从服务器中读取的诗歌名。

import java.io.*;
import java.net.*;
public class DailyPoetryClient {
    public void go() {
         try {
            Socket s = new Socket("127.0.0.1",5000);
    		//【代码一】   

            System.out.println("Today's Poetry: "+poetry);
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    public static void main(String[] args) {
        DailyPoetryClient client = new DailyPoetryClient();
        client.go();
    }
}

(2)在项目中,新建Java类,命名为“DailyPoetryServer”。在DailyPoetryServer.java文件中,定义服务器类。服务器类的主要功能:向客户端随机输出一首诗歌名。

import java.net.*;
import java.io.*;

public class DailyPoetryServer {
    String [] poetrys = {"太阳颂","生如夏花","飞鸟集","园丁集","吉檀迦利","闲暇"};
    public void go() {
        try {
           /*【代码二】*/;
            //【代码三】

            PrintWriter writer = new PrintWriter(sock.getOutputStream());
            String poetry = getPoetry(); //获取诗歌名
          
            //【代码四】
			sock.close();
            System.out.println(poetry);
			
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
	//随机返回诗歌名
    private String getPoetry() {
        int random = (int)(Math.random()*poetrys.length);
        /*【代码五】*/;
    }
    public static void main(String [] args) {
        DailyPoetryServer server = new DailyPoetryServer();
        server.go();
    }
}

2、通过多线程编程,改写服务器类DailyPoetryServer,以实现该服务器能同时服务多个客户端。
【说明】在项目中,新建Java类,命名为“DailyPoetryServer2”。在DailyPoetryServer2.java文件中,定义多线程的服务器类DailyPoetryServer2。

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class DailyPoetryServer2 {
String[] poetrys = {"太阳颂", "生如夏花", "飞鸟集", "园丁集", "吉檀迦利", "闲暇"};

    public void go() {
        try {
            ServerSocket serverSocket = new ServerSocket(5000);
            System.out.println("服务器已启动,等待客户端连接...");

            while (true) {
                Socket sock = serverSocket.accept();
                Thread clientHandler = new ClientHandler(sock);
                clientHandler.start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
}

    private String getPoetry() {
        int random = (int) (Math.random() * poetrys.length);
        return poetrys[random];
}

    public static void main(String[] args) {
        DailyPoetryServer2 server = new DailyPoetryServer2();
        server.go();
}

    private class ClientHandler extends Thread {
        private Socket clientSocket;

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
        }

        @Override
        public void run() {
            try {
                PrintWriter writer = new PrintWriter(clientSocket.getOutputStream(), true);
                String poetry = getPoetry();
                writer.println(poetry);
                System.out.println("已发送诗歌给客户端: " + poetry);
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3、创建简单的TCP聊天程序。
在这里插入图片描述

(1)在项目中,新建Java类,命名为“SimpleChatClient”。在SimpleChatClient.java文件中,定义客户端类。客户端类的主要功能:实现聊天界面,当用户在文本框中输入一行文本,单击“发送”按钮,文本信息将传送给服务器。

import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class SimpleChatClient {    
    JTextArea incoming;
    JTextField outgoing;
    BufferedReader reader;
    PrintWriter writer;
    Socket socket;

    public static void main(String[] args) {
        new SimpleChatClient().go();
    }

    public void go() {
        JFrame frame = new JFrame("聊天客户端");
        JPanel mainPanel = new JPanel();
        JPanel panel = new JPanel();
        incoming = new JTextArea(15, 30);
        incoming.setLineWrap(true);//设置在行过长的时候是否要自动换行
        incoming.setWrapStyleWord(true);//设置在单词过长的时候是否要把长单词移到下一行。
        incoming.setEditable(false);
        JScrollPane qScrollPane = new JScrollPane(incoming);
        qScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        qScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        outgoing = new JTextField(20);
        JButton sendButton = new JButton("发送");
        //设置按钮的监听器
        sendButton.addActionListener(new SendButtonListener());
        panel.add(outgoing);
        panel.add(sendButton);
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
        mainPanel.add(qScrollPane);
        mainPanel.add(panel);
        frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        //窗体关闭,则退出应用程序
        frame.setResizable(false); //禁止改变窗体大小
        frame.pack();
        frame.setVisible(true);
frame.getRootPane().setDefaultButton(sendButton);
//设置在窗口中按下回车键时,单击了sendButton        
        setUpNetWoking();//连接服务器
        //创建一个线程,用于接收服务器的消息
        Thread readerThread = new Thread(new IncomingReader());
        readerThread.start();
    }
	
	//将“发送”按钮的事件处理类定义为内部类
	public class SendButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent ev) {
           //请手动输入代码
			try {
                writer.println(outgoing.getText());
                writer.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
            //清空文本框
            outgoing.setText("");
            outgoing.requestFocus();
        }
    }

	private void setUpNetWoking() {
        //请手动输入代码
try {
     socket = new Socket("127.0.0.1",5000);
     InputStreamReader streamReader = new InputStreamReader(socket.getInputStream());
     reader = new BufferedReader(streamReader);
     writer = new PrintWriter(socket.getOutputStream());
      System.out.println("networking established");
     } catch (IOException e) {
            e.printStackTrace();
        }
    }
	//将接收服务器端消息的线程定义为内部类
    public class IncomingReader implements Runnable {
		//请手动输入代码   
		@Override
        public void run() {
            String message;
            try {
                while ((message = reader.readLine()) != null){
                    System.out.println("read:"+message);
                    incoming.append(message+"\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            
    }
} 

public void actionPerformed((ActionEvent ev)的实现代码:
在这里插入图片描述

setUpNetWoking()的实现代码如下:
在这里插入图片描述

IncomingReader类的实现代码如下:
在这里插入图片描述

(2)在项目中,新建Java类,命名为“SimpleChatServer”。在SimpleChatServer.java文件中,定义服务器类。服务器的主要功能:将接收到的信息,群发给所有的客户端。

import java.io.*;
import java.net.*;
import java.util.*;
public class SimpleChatServer {

ArrayList<PrintWriter> clientOutputStreams;

    public static void main(String[] args) {
        new SimpleChatServer().go();
    }
    public void go() {
		//请手动输入代码  
		clientOutputStreams = new ArrayList<>();
        try {
            ServerSocket serverSocket = new ServerSocket(5000); // 服务器监听的端口
            System.out.println("服务器已启动,等待客户端连接...");
            while (true) {
                Socket clientSocket = serverSocket.accept(); // 接受客户端连接
                PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
                clientOutputStreams.add(writer);
                Thread t = new Thread(new ClientHandler(clientSocket));
                t.start();
                System.out.println("客户端已连接");
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        }     
    }
    public class ClientHandler implements Runnable {
        BufferedReader reader;
        Socket socket;
        public ClientHandler(Socket clientSocket) {
			//请手动输入代码
			try{
				socket = clientSoket;
			InputStreamReader isReader=new InputStreamReader(socket.getInputStream());
			reader = new BufferedReader(isReader);
}catch(IOException e){
	e.printStackTrace();
}
        }
public void run() {
            String message;
            try {
                while ((message = reader.readLine()) != null) {
                    System.out.println("read: " + message);
                    tellEveryone(message);
                }
            } catch (Exception ex) {
                //ex.printStackTrace();
            }
}
    }
    public void tellEveryone(String message) {
		//请手动输入代码 
		   Iterator<PrintWriter> it = clientOutputStreams.iterator();
        while (it.hasNext()){
            try {
                PrintWriter writer = it.next();
                writer.println(message);
                writer.flush();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }      
    }
}

public void go()的实现代码:
在这里插入图片描述

public ClientHandler(Socket clientSocket)的定义:
在这里插入图片描述

public void tellEveryone(String message)的定义:
在这里插入图片描述

实验具体实现

import java.io.*;
import java.net.*;
public class DailyPoetryClient {
    public void go() {
         try {
            Socket s = new Socket("127.0.0.1",5000);
    		//【代码一】   
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));    
        String poetry = reader.readLine();
            System.out.println("Today's Poetry: "+poetry);
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    public static void main(String[] args) {
        DailyPoetryClient client = new DailyPoetryClient();
        client.go();
    }
}
import java.net.*;
import java.io.*;

public class DailyPoetryServer {
    String [] poetrys = {"太阳颂","生如夏花","飞鸟集","园丁集","吉檀迦利","闲暇"};
    public void go() {
        try {
            ServerSocket serverSocket = new ServerSocket(5000)/*【代码二】*/;
            //【代码三】
Socket sock = serverSocket.accept();
            PrintWriter writer = new PrintWriter(sock.getOutputStream());
            String poetry = getPoetry(); //获取诗歌名
            writer.println(poetry);
            //【代码四】
			sock.close();
            System.out.println(poetry);
			
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
	//随机返回诗歌名
    private String getPoetry() {
        int random = (int)(Math.random()*poetrys.length);
        return poetrys[random]/*【代码五】*/;
    }
    public static void main(String [] args) {
        DailyPoetryServer server = new DailyPoetryServer();
        server.go();
    }
}

四、资料自提

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-Z_Nuyoah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值