实验八:Java网络编程

实验八:Java网络编程

一、实验目的

  1. 掌握URLConnection与URL的关系及编程方法。
  2. 理解网络流的概念。
  3. 掌握基于TCP/IP的Socket/ServerSocket编程方法。
  4. 掌握基于UDP的DatagramSocket/DatagramPacket编程方法。

二、实验内容及步骤

1. 基于TCP/IPSocket通信

1-1 基于TCP/IPSocket通信的服务器端代码如下:

import java.io.DataInputStream;

import java.net.ServerSocket;  //服务端套接字

import java.net.Socket;   //套接字

 

public class Server1{    //服务端

    public static void main(String[] args) throws Exception {

        ServerSocket ss= new ServerSocket(7777);  //设置服务器 的监听端口

        System.out.println("Server started.");

        while(true){   //始终监听

            //监听客户端请求

            Socket cs = ss.accept();  //可能产生阻塞(等待)的原因是没有客户端请求

            DataInputStream dis = new DataInputStream(cs.getInputStream());//

            System.out.println(dis.readUTF());  //输出来自客户端传送的信息

            dis.close();

            cs.close();

        }

    }

}

运行结果:

 

相关要点如下:

  • 先运行服务器端,然后再运行客户端,客户端程序运行后,服务器端会输出来自客户端的信息
  • 服务器打开后会阻塞线程知道监听到端口中的信息并将其输出

1-2 基于TCP/IPSocket通信的客户端代码如下:

import java.io.DataOutputStream;  //数据输出字节流

import java.net.Socket;

 

public class Client1 {  //客户端

    public static void main(String[] args) throws Exception {

        // 第一个参数为服务器IP

        // 第二参数7777为服务器端口,与创建ServerSocket时使用的端口一致

        Socket s = new Socket("127.0.0.1", 7777);  //创建客户端

 

        DataOutputStream dos = new DataOutputStream(s.getOutputStream());

        dos.writeUTF("Hello Server!"); // 向服务器传送信息

        //System.out.println("客户端信息已发送。");

 

        Thread.sleep(5000);  //休眠5秒

 

        dos.flush();

        dos.close(); // 超类方法

        s.close();

    }

}

相关要点如下:

  • 通过数据输出流向服务器发送消息,端口必须与服务器端口一致
  • 同一网段的不同电脑,也可以完成连接

2. 基于UDPSocket通信

2-1 服务器端程序代码如下:

import java.net.DatagramPacket;

import java.net.DatagramSocket;

 

public class Server2 {

    @SuppressWarnings("resource")

    public static void main(String[] args) throws Exception{

 

        byte buf[]=new byte[1024];

 

        //设置数据报文包

        DatagramPacket dp=new DatagramPacket(buf,buf.length);

 

        //创建报文接收端口,在客户端程序会使用该端口号

        DatagramSocket ds=new DatagramSocket(5678);

 

        System.out.println("Server started.");

        while(true){

            ds.receive(dp);  //阻塞式的接收

            System.out.println(new String(buf,0,dp.getLength())+",Server!");

        }

    }

}

2-2 客户端程序代码如下:

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetSocketAddress;

 

public class Client2 {

    public static void main(String[] args) throws Exception{       

        byte[] buf=(new String("Hello")).getBytes();   

        //定义数据报文包对象,包含了服务器地址及端口,InetSocketAddress继承抽象类SocketAddress

        DatagramPacket dp=new DatagramPacket(buf,buf.length,new InetSocketAddress("127.0.0.1",5678));  

        DatagramSocket ds=new DatagramSocket(9999); //创建对象         

        ds.send(dp);  //发送到指定的服务器端口

        ds.close();

    }

}

运行结果:

 

相关要点如下:

  • 创建服务端,需要使用大于1024的端口
  • 创建客户端,需要使用服务器端口

3. 简易图形用户界面聊天程序

3-1 服务器代码如下:

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.PrintStream;

import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

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 Server3 extends JFrame{

          static JTextArea area;

          JTextField field;

          JButton button;

          static PrintStream writer;

          public Server3(){

                   this.setTitle("服务器");

                   this.setSize(400,500);

                   area = new JTextArea(25,30);

                   area.setEditable(false);

                   field = new JTextField(20);

                   button = new JButton("提交");

                   JPanel panel = new JPanel();

                   JScrollPane sp = new JScrollPane(area);

                   this.add(sp,BorderLayout.CENTER);

                   panel.add(field);

                   panel.add(button);

                   this.add(panel,BorderLayout.SOUTH);

                   this.setVisible(true);

                   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                  

                   button.addActionListener(new ActionListener(){

 

                             @Override

                             public void actionPerformed(ActionEvent e) {

                                      String text = field.getText();

                                      writer.println(text);

                                      area.append("我:"+text+" ");

                                      field.setText("");

                             }

                            

                   });

          }

          public static void main(String[] args) throws Exception {

                   Server3 s = new Server3();

                   ServerSocket server = new ServerSocket(8899);

                   System.out.println("开始监听...");

                   Socket socket = server.accept();

                   InetAddress address = socket.getInetAddress();

                   String name = address.getLocalHost().getHostName();

                   System.out.println(name+"已连接");

                   BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                   writer = new PrintStream(socket.getOutputStream(), true);

                   while (true) {

                             String line = null;

                             line = reader.readLine();

                             if (line != null) {         

                                                area.append("客户端:"+line+" ");

                             }

 

                   }

          }

    }

相关要点如下:

  • 该服务器通过获取端口中的输入流读信息,并将信息通过输出流发送给客户端
  • 在发送消息的同时,服务器也会将信息写到面板上

3-3 客户端代码如下:

import java.awt.BorderLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.PrintStream;

import java.io.PrintWriter;

import java.net.Socket;

 

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 Client3 extends JFrame{

 

          static JTextArea area;

          JTextField field;

          JButton button;

          static PrintWriter writer;

          public Client3(){

                   this.setTitle("客户端");

                   this.setSize(400,500);

                   area = new JTextArea(25,30);

                   area.setEditable(false);

                   field = new JTextField(20);

                   button = new JButton("提交");

                   JScrollPane sp = new JScrollPane(area);

                   JPanel panel = new JPanel();

                   this.add(sp,BorderLayout.CENTER);

                   panel.add(field);

                   panel.add(button);

                   this.add(panel,BorderLayout.SOUTH);

                   this.setVisible(true);

                   this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                  

                   button.addActionListener(new ActionListener(){

 

                             @Override

                             public void actionPerformed(ActionEvent e) {

                                      String text = field.getText();

                                      writer.println(text);

                                      area.append("我:"+text+" ");

                                      field.setText("");

                             }

                            

                   });

          }

          public static void main(String[] args) throws Exception{

                   Client3 c = new Client3();

                   Socket socket = new Socket("127.0.0.1",8899);

                   OutputStream out = socket.getOutputStream();

                   BufferedReader reader1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                   writer = new PrintWriter(out,true);

                   System.out.println("已经成功和服务器连接...");

                   while(true){

                             String line = reader1.readLine();

                             area.append("服务器:"+line+" ");

                   }

          }

 

}

运行效果:

 

相关要点如下:

  • 获取名字信息和输出信息后,将其发送到服务器,再接收服务器返回的信息并将其显示

三、实验小结

  • 分析UDP通信和TCP通信的利弊
  • 总结多线程通信的具体实现方法
原文地址:https://www.cnblogs.com/fx0102/p/13196195.html