欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java第十八章-网络通信

程序员文章站 2023-12-23 19:01:45
...

绪论

通过计算机网络,相互连接的计算机彼此之间可以进行数据交流,如要编写网络应用程序,首先要明确这些应用程序所使用的网络协议。

局域网与因特网

Java第十八章-网络通信

//服务器是指提供信息的计算机或是应用程序
//客户机是指请求信息的计算机或是程序
//局域网(LAN)是指一群通过一定形式连接起来的计算机
//有LAN延伸到更大的范围,称为广域网(WAN)
//我们熟知的因特网,有无数的LAN和WAN组成

网络协议

IP协议

//因特网采用的时TCP/IP协议,因特网上有数千上万个主机,每一个主机分配一个地址即为IP地址。目前IP地址由四个字节组成即32位二进制数称为IPv4,通常取每个字节的十进制数且每个字节有一个点做分隔符,例如:192.168.1.1
//TCP/IP模式是一种层次结构共分为4层。应用层、传输层、互联网层、网络层,各层功能有一定的独立性。

Java第十八章-网络通信

TCP与UDP协议

//TCP:传输控制协议
//UDP:用户数据报协议
//TCP协议时一种以固接连接为基础的协议,可以保证数据准确达到,而且抵达的数据排列顺序与输送时相同,应用一些可靠性要求比较高的场所
//UDP协议无连接通信协议,不保证数据的可靠性。而且无法保证顺序,应用一些数据准确性要求不是很高的场所。

端口和套接字

//一班而言,一台计算机只有单一的连接到网络的物理连接,所有的数据都通过此连接对内外送达指定的计算机,这就是端口(port)。网络程序的端口并非真实存在。端口范围0~65535之间的整数HTTP使用80端口,FTP使用21端口。
//0~1023之间的端口用于一些知名的网络服务程序。普通用户选取1024以上。
//网络程序中的套接字(Socket)用于将应用程序与端口连接起来。

Java第十八章-网络通信

TCP程序设计基础

//利用TCP进行·通信的俩个程序具有主次之分,一个称为服务器程序,另一个称为客户机程序。

Java第十八章-网络通信

InetAddress类

//此类是与IP地址相关的类,利用该类可以获取IP地址、主机地址等信息。

Java第十八章-网络通信

package 网络通信;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Address {
public static void main(String args[]) {
    //创建InetAddress类对象
    InetAddress ip;
    try {
        //实例化该类对象
        ip = InetAddress.getLocalHost();
        //获取本机名与IP地址
        String localname  = ip.getHostName();
        String loacalip = ip.getHostAddress();
        System.out.println("本机名" + localname);
        System.out.println("本机IP地址" + loacalip);
    } catch (UnknownHostException e) {
        e.printStackTrace();
    }
}
}

ServerSocket类

//此类表示服务器套接字,其主要功能是等待来自网络的请求。它也可以通过指定的端口来等待连接的套接字。

Java第十八章-网络通信

TCP网络程序

//单向通信:只要求客户机向服务器发送消息,不要求服务器向客户机发送消息。
//简单单向通信f服务端程序案例:

package 网络通信;

import 输入输出.MyZip;

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

public class MyTcp {
//创建BufferedReader类对象
private BufferedReader reader;
//创建ServerSocket类对象
private ServerSocket serverSocket;
//创建Socket对象
private Socket socket;
void getserver() {
    try {
        //实例化ServerSocket类对象
        serverSocket = new ServerSocket(8998);
        System.out.println("服务器套接字已创建成功");
        //如果套接字是连续状态的
        while (true) {
            System.out.println("等待客户机的连接");
            //实例化Socket类对象
            socket = serverSocket.accept();
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            getClientMessage();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
private void getClientMessage() {
    try {
        //如果客户机是连接状态
        while (true) {
            //获取客户信息
            System.out.println("客户机" + reader.readLine());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    try {
        //关闭流和套接字
        if (reader != null) {
            reader.close();
        }
        if (socket != null) {
            socket.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public static void main(String args[]) {
    //实例化本类对象
    MyTcp myTcp = new MyTcp();
    myTcp.getserver();
}
}

Java第十八章-网络通信
//客户端案例,实现将用户在文本框中输入的信息发送至服务器,将文本框中的输入的信息显示在客户端的文本域中

package 网络通信;

import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.PrintWriter;
import java.net.Socket;

public class MyClient  extends JFrame {
//声明各类对象
private PrintWriter printWriter;
Socket socket;
private JTextArea jTextArea = new JTextArea();
private JTextField jTextField = new JTextField();
Container cc;
public MyClient(String title) {
    //调用父类构造方法
    super(title);
    //实例化对象
    cc = this.getContentPane();
    final JScrollPane jScrollPane = new JScrollPane();
    jScrollPane.setBorder(new BevelBorder(BevelBorder.RAISED));
    getContentPane().add(jScrollPane,BorderLayout.CENTER);
    jScrollPane.setViewportView(jTextArea);
    //将文本框放在窗体的最下部
    cc.add(jTextField,"South");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jTextField.addActionListener(new ActionListener() {
        //绑定事件
        public void actionPerformed(ActionEvent e) {
            //将本文框的信息写入流
            printWriter.println(jTextField.getText());
            //将文本框的信息显示在文本域中
            jTextArea.append(jTextField.getText() + "\n");
            jTextArea.setSelectionEnd(jTextArea.getText().length());
            //将文本框清空
            jTextField.setText("");
        }
    });
}
//连接套接字的方法
private void connect() {
    //文本域中提示信息
    jTextArea.append("尝试连接\n");
    try {
        //实例化Socket类对象
        socket = new Socket("127.0.0.1",8998);
        printWriter = new PrintWriter(socket.getOutputStream(),true);
        //文本域中提示信息
        jTextArea.append("完成连接\n");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public static void main(String args[]) {
    MyClient myClient = new MyClient("向服务器送数据");
    myClient.setSize(200,200);
    myClient.setVisible(true);
    myClient.connect();
}
}

Java第十八章-网络通信

UDP程序设计

//用户数据报协议传输信息更快,但不提供可靠的保证。

Java第十八章-网络通信

//主机不断地播出天气预报,可以保证加入到同一组的主机随时可接收到广播信息。接受这将正在接收的信息放在一个文本域中,并将接受的全部信息放入另一个文本域中

package 网络通信;

import java.net.DatagramPacket;
import java.net.InetAddress;	
import java.net.MulticastSocket;

public class Weather extends Thread{
String weather = "节目预报:八点有大型晚会,请收听";
//定义端口
int port = 9898;
//创建InetAddress类对象
InetAddress inetAddress = null;
//声明多点广播套接字
MulticastSocket socket = null;
Weather() {
    try {
        //实例化InetAddress,指定地址
        inetAddress = InetAddress.getByName("224.255.10.0");
        //实例化多点字广播套接字
        socket = new MulticastSocket(port);
        //指定发送范围的本地网络
        socket.setTimeToLive(1);
        //加入广播组
        socket.joinGroup(inetAddress);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void run() {
    while (true) {
        //声明DatagramPacket对象
        DatagramPacket packet = null;
        //声明字节数
        byte[] data = weather.getBytes();
        //将数据包打印
        packet = new DatagramPacket(data, data.length, inetAddress, port);
        //将广播信息输出
        System.out.println(new String(data));
        try {
            //发送数据
            socket.send(packet);
            sleep(3000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public static void main(String args[]) {
    Weather w = new Weather();
    w.start();
}
}

Java第十八章-网络通信

//单击开始接收按钮,系统开始接收主机播出的信息,停止接收按钮则停止接收

package 网络通信;

import javafx.scene.layout.BorderRepeat;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class Receive extends JFrame implements Runnable, ActionListener {
int port;
InetAddress group = null;
//创建多点广播套接字对象
MulticastSocket socket = null;
//创建按钮对象
JButton ince = new JButton("开始接收");
JButton stop = new JButton("停止接收");
//显示接收广播的文本域
JTextArea inceAr = new JTextArea(10,10);
JTextArea inced = new JTextArea(10,10);
//创建Thread对象
Thread thread;
//创建boolean类型变量
boolean b = false;
public Receive() {
    //调用父类方法
    super("广播数据报");
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    thread = new Thread(this);
    //绑定ince按钮的单击事件
    ince.addActionListener(this);
    //绑定stop按钮的单击事件
    stop.addActionListener(this);
    //指定文本域中文字颜色
    inceAr.setForeground(Color.blue);
    //创建Jpanel对象
    JPanel north = new JPanel();
    //将按钮添加到面板上
    north.add(ince);
    north.add(stop);
    //将north放在窗体上部
    add(north,BorderLayout.NORTH);
    JPanel center = new JPanel();
    center.setLayout(new GridLayout(1,2));
    //将文本域添加到到面板
    center.add(inceAr);
    center.add(inced);
    add(center, BorderLayout.CENTER);
    //刷新
    validate();
    port = 9898;
    try {
        //指定接收地址
        group = InetAddress.getByName("224.255.10.0");
        //绑定多点广播套接字
        socket = new MulticastSocket(port);
        //加入广播组
        socket.joinGroup(group);
    } catch (Exception e) {
        e.printStackTrace();
    }
    setBounds(100,50,360,380);
    setVisible(true);
}
public void run() {
    while (true) {
        byte[] data = new byte[1024];
        DatagramPacket packet = null;
        //待接收的数据包
        packet = new DatagramPacket(data, data.length, group, port);
        try {
            //接收数据包
            socket.receive(packet);
            //获取数据包中的内容
            String message = new String(packet.getData(), 0, packet.getLength());
            //将接收内容显示在文本域中
            inceAr.setText("正在接收的内容:\n" + message);
            //每条信息为一行
            inced.setText(message + "\n");
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (b == true) {
            break;
        }
    }
}
//点击事件
public void actionPerformed(ActionEvent e) {
    //单击按钮ince触发的事件
    if (e.getSource() == ince) {
        //设置颜色按钮
        ince.setBackground(Color.red);
        stop.setBackground(Color.black);
        //如果线程不处于“新建状态”
        if (!(thread.isAlive())) {
            thread = new Thread(this);
        }
        thread.start();
        b = false;
    }
    //单击按钮stop触发的事件
    if (e.getSource() == stop) {
        //设置按钮颜色
        ince.setBackground(Color.yellow);
        stop.setBackground(Color.red);
        b = true;
    }
}
public static void main(String args[]) {
    Receive rec = new Receive();
    rec.setSize(460,200);
}
}

Java第十八章-网络通信

上一篇:

下一篇: