计算机网络实现了堕胎计算机间的互联,使得它们彼此之间能够进行数据交流。网络应用程序就是再已连接的不同计算机上运行的程序,这些程序借助于网络协议,相互之间可以交换数据,编写网络应用程序前,首先必须明确网络协议TCP/IP协议是网络应用程序的首选
网络程序设计基础:
 网络程序设计编写始于其他计算机进行通信的程序,java已经将网络程序所需要而定元素封装成不同的类,用户只要床啊金这些类的对象,使用相应的方法即使不举报相关的网络知识,也是可以编写除高质量的网络通信程序的,
本章最主要的是TCP和UDP两个部分 他们两主要的区别就是一个是一对一通信 一个是一对多通信 当然两者都有各自的优势和劣势,接下来先讲解 TCP部分
TCP程序
 TCP程序的通信方式呢 是一对一的   步骤是  先要打开服务器然后客户端连接服务器  先是尝试客户端是否能够接收到信息  如果可以接收到信息的话  这时服务器将会把文件传输给客户端,这样的话 能够保证客户端可以接收到信息  ,劣势呢就是每次都是要这样子 所以效率对比起UDP来说慢下了好多  以下代码将会进行讲解
客户端代码:
package tcp;
  
 import java.io.*;
 import java.net.Socket;
 import java.util.Scanner;
  
 /**
  * Socket客户端
  **/
 public class SocketClient {
     public static void main(String[] args) {
         Socket s = null;
         try {
             // 与ip为127.0.0.1、端口为12345的服务端建立连接
             s = new Socket("127.0.0.1", 12345);
  
             // 创建输入流接收服务端发送的消息(字节流)
             InputStream is = s.getInputStream();
             // 将服务端返回的字节流转化为字符流
             InputStreamReader isr = new InputStreamReader(is);
             // 创建字符流读取缓冲区,方便每行读取
             BufferedReader br = new BufferedReader(isr);
  
             // 创建输出流返回消息
             OutputStream os = s.getOutputStream();
             // 创建输出流缓冲
             PrintWriter pw = new PrintWriter(os);
  
             // 创建发送消息的线程
             Runnable rOut = () -> {
                 boolean flag = true;
                 while (flag) {
                     try {
                         // 接收控制台输入
                         Scanner scan = new Scanner(System.in);
                         String msg = scan.nextLine();
                         // 将输入写入缓冲
                         pw.println(msg);
                         // 将缓冲内的数据推送至服务端并清空缓冲区
                         pw.flush();
                     } catch (Exception e) {
                         flag = false;
                         e.printStackTrace();
                     }
                 }
             };
  
             // 创建接收消息的线程
             Runnable rIn = () -> {
                 boolean flag = true;
                 while (flag) {
                     try {
                         // 逐行读取服务端返回的消息并打印
                         String str = br.readLine();
                         System.out.println("服务端的消息:" + str);
                     } catch (IOException e) {
                         flag = false;
                         e.printStackTrace();
                     }
                 }
             };
  
             // 启动两个线程
             Thread tOut = new Thread(rOut);
             Thread tIn = new Thread(rIn);
             tOut.start();
             tIn.start();
         }catch (IOException e) {
             try {
                 // 释放资源
                 s.close();
             } catch (Exception exception) {
                 exception.printStackTrace();
             }
             e.printStackTrace();
         }
     }
 }
服务端代码:
package tcp;
 import java.io.*;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.Scanner;
  
 /**
  * Socket服务端
  **/
 public class SocketServer {
     public static void main(String[] args) {
         ServerSocket ss = null;
         Socket s = null;
         try {
             // 创建监听端口为12345的Socket服务端
             ss = new ServerSocket(12345);
             System.out.println("服务端Socket服务已建立,等待客户端连接...");
             // 通过ss.accept()开始持续监听12345端口,当有连接时获取收到的包装成Socket的客户端对象
             s = ss.accept();
             // 获取客户端的IP地址和端口号
             String ip = s.getInetAddress().getHostAddress();
             int port = s.getPort();
             System.out.println("服务端与 " + ip + ":" + port + " 已建立连接");
  
             // 创建输入流接收客户端发送的消息(字节流)
             InputStream is = s.getInputStream();
             // 将客户端发送的字节流转化为字符流
             InputStreamReader isr = new InputStreamReader(is);
             // 创建字符流读取缓冲区,方便每行读取
             BufferedReader br = new BufferedReader(isr);
  
             // 创建输出流返回消息
             OutputStream os = s.getOutputStream();
             // 创建输出流缓冲
             PrintWriter pw = new PrintWriter(os);
  
             // 创建接受信息的线程
             Runnable rIn = () -> {
                 boolean flag = true;
                 while (flag) {
                     try {
                         // 逐行读取客户端发送的消息并打印
                         String str = br.readLine();
                         System.out.println("客户端的消息:" + str);
                     } catch (IOException e) {
                         flag = false;
                         e.printStackTrace();
                     }
                 }
             };
  
             // 创建发送消息的线程
             Runnable rOut = () -> {
                 boolean flag = true;
                 while (flag) {
                     try {
                         // 接收控制台输入
                         Scanner scan = new Scanner(System.in);
                         String msg = scan.nextLine();
                         // 将输入写入缓冲
                         pw.println(msg);
                         // 将缓冲内的数据推送至客户端并清空缓冲区
                         pw.flush();
                     } catch (Exception e) {
                         flag = false;
                         e.printStackTrace();
                     }
                 }
             };
  
             // 开启两个线程
             Thread tIn = new Thread(rIn);
             Thread tOut = new Thread(rOut);
             tIn.start();
             tOut.start();
         } catch (IOException e) {
             try {
                 // 释放资源
                 ss.close();
                 s.close();
             } catch (Exception exception) {
                 exception.printStackTrace();
             }
             e.printStackTrace();
         }
     }
 }



UDP程序
 UDP程序跟TCP程序不同的地方呢  TCP通信是一对一通信 如果要一下通知好多个人的话 就需要一个一个来通信  所以这时将会需要UDP了  UDP的优势就在于效率高 但是不稳定的地方呢  就是效率高但是不一定每个人都能看到  就像老师在台上讲课 总有一些学生会在台下玩手机 或者带耳机  不一定每一个人都能够接受得到  这就是UDP的不稳定的地方 ,接下来使用代码来讲解:
广播类代码如下:
package udp;
  
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 import java.net.MulticastSocket;
 //广播  先运行
 public class Notification  extends Thread{
     String weather = "节目预报:八点有大型晚会,请收听";//发送消息
     int port = 9898;//端口号
     InetAddress iaddress = null;
     MulticastSocket socket = null;//多点广播套接字
     
     Notification(){
         try {
             iaddress = InetAddress.getByName("224.255.10.0");//地址
             socket = new MulticastSocket(port);//实例化多点广播套接字
             socket.setTimeToLive(1);//指定发送范围是本地网络
             socket.joinGroup(iaddress);//加入广播组
         }catch(IOException e){
             e.printStackTrace();//输出异常信息
         }
     
     }
     public void run(){//run方法
         while(true) {
             DatagramPacket packet = null;//数据包
             byte data[]=weather.getBytes();//字符串消息的字节数组
             packet =  new  DatagramPacket(data,data.length,iaddress,port);//将数据打包
             System.out.println(weather);//控制台打印消息
             try {
                 socket.send(packet);//发送数据
                 sleep(3000);//让线程休眠3000毫秒
             }catch(IOException e){
                 e.printStackTrace();
             }catch(InterruptedException e) {
                 e.printStackTrace();
             }
         }    
             }
     public static void main(String[]args) {
         Notification w =new Notification();
         w.start();//启动线程
     }
 }
接收类代码如下:
package udp;
  
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.InetAddress;
 import java.net.MulticastSocket;
  
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
 import javax.swing.JTextArea;
 import javax.swing.WindowConstants;
 //接收  后运行
 public class Receive extends JFrame implements Runnable, ActionListener {
     int port ;//端口
     InetAddress group =null;//广播组地址
     MulticastSocket socket = null;//多点广播套接字对象
     JButton inceBtn = new JButton("开始接收");
     JButton stopBtn = new JButton("停止接收");
     JTextArea inceAr = new JTextArea(10,10);//显示接收广播的文本域
     JTextArea inced = new JTextArea(10,10);
     Thread thread ;
     boolean stop = false;//定制接受信息状态
     
     public Receive () {
         setTitle("广播数据包");
         setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
         thread = new Thread(this);
         inceBtn.addActionListener(this);//绑定按钮ince的单击事件
         stopBtn.addActionListener(this);//绑定按钮stop的单击事件
         inceAr.setForeground(Color.blue);//指定文本域中文字的颜色
         
         JPanel north = new JPanel();
         north.add(inceBtn);//将按钮添加到面板north上
         north.add(stopBtn);
         add(north,BorderLayout.NORTH);//将north放置在窗体的上部
         JPanel center = new JPanel();//创建面板对象center
         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(IOException e){
             e.printStackTrace();//输出异常信息
         }
         setBounds(100,50,360,380);//设置布局
         setVisible(true);//将窗体设置为显示状态
     }
     public void run() {//run方法
         while (!stop) {
             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.append(message+"\n");//每条信息为一行
             }catch(IOException e ) {
                 e.printStackTrace();//输出异常信息
             }
             
         }
     }
     public void actionPerformed(ActionEvent e) {//单机按钮ince出发时间
         if(e.getSource()==inceBtn) {
             inceBtn.setBackground(Color.red);//设置按钮颜色
             stopBtn.setBackground(Color.yellow);
             if(!(thread.isAlive())) {//如线程不处于“新建状态”
                 thread = new Thread(this);//实例化Thread对象
             }
             thread.start();//启动线程
             stop = false;//开始接受信息
         }
         if(e.getSource()== stopBtn) {//单机按钮stop出发时间
             inceBtn.setBackground(Color.yellow);//设置按钮亚瑟
             stopBtn.setBackground(Color.red);
             stop = true;//停止接收信息
         }
     }
     public static void main(String[]args) {
         Receive rec = new Receive();
         rec.setSize(460,200);
     }
 }






















