二十三、Java基础--------网络编程

        Java中另一个重要技术就是网络编程了,为了更好的学习web方向的知识,有必要对java之网络编程好好学习,本文将围绕网络编程技术进行分析。

常见的网络协议:UDP、TCP

UDP

       1、 将数据源和目的封装为数据包,不需要建立连接

        2、每个数据包大小在64K内

        3、因为面向无连接,所以不可靠(丢失数据)

        4、不需要连接,速度快

        常见的UDP:聊天、视频会议、桌面共享等等

TCP

       1、 建立连接,形成传输数据的通道

        2、在连接中进行大量数据的传输

        3、通过三次握手完成连接,是可靠协议

        4、必须建立连接,效率会相对较低

Socket

    Socket就是为网络服务的一种机制,通信两段都有socket,网络通信其实就是socket间的通信。数据自练个socket间通过IO传输。

UDP建立连接步骤

    需求:通过UDP传输方式,将一段文字发送出去,另一端进行接受并打印

    思路:

    发送端:

                1、建立UDP socket服务

                2、提供数据,将数据封装到数据包中

                3、通过socket服务,将数据包发送出去

                4、关闭资源

    接受端:

                1、定义UDP socket服务,通常会监听一个端口,方便与明确该应用程序处理的对象。

                2、定义一个数据包,以便于存储接收到数据,数据包对象中提供了更多操作接收数据处理的方法

                3、通过socket服务的receive方法,将接收到的数据包存于已定义的数据包中。

                4、通过数据对象特有的功能将这些不同的数据取出,并进行后续的处理

                5、关闭资源

具体步骤:

    发送端:

        1、创建UDP服务,通过DatagramSocket对象

            DatagramSocket ds =new DatagramSocket();

        2、确定数据并封装成数据包

            DatagramPacket dp=new DatagramPacket(buf,buf.length,InetAdress,port)

        3、通过socket服务,将已经封包的数据进行发送

           ds.senf(dp)

        4、关闭资源

           ds.close();

    接收端:

                1、创建UDP socket,建立端点(指明监听的端口)

                    DatagramSocket ds =new DatagramSocket(100010);

               2、 定义数据包用于存储接受进来的数据

                     Byte []by=new byte[1024];

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

                3、通过服务的receive方法接受数据,并存于到已定义的数据包中

                   ds.receive(dp);

                4、通过数据包的特有方法去除取出其中的数据

                   String s=new String(dp.getData());

                5、关闭资源

                   ds.close();

TCP建立连接步骤

    需求:建立TCP链接,并传输一段数据到服务器,服务器接收数据并打印该数据

    客户端

               1、 建立服务端点,指明主机名以及端口号

                     Socket s=new Socket("127.0.0.1",10010);

                2、读取客户端要传送的数据

                    byte []by="TCP I am coming".getBytes();

                3、通过socket输出流将数据发给服务器

                    OutputStream out=s.getOutputStream();

                    out.wirte(by);

                5、关闭资源

                   s.close();

    服务端:

               1、 建立服务端并指明监听端口

                    ServerSocket ss=new ServerSocker=t(10010);

                2、开启服务,并接受数据

                    Scoket s=ss.accept();

                3、读取接受到的数据,并封装成包(本例只是打印)

                     InputStream in=s.getInputStream();

                     int len=0;

                     byte by[]=new byte[1024];

                    len=in.read(by);

                    System.out.println(new String(by,0,len));

                4、关闭资源

                    s.close();

案例分析:

    需求:编写一个UDP聊天程序:
            分析:
                有接受数据的部分,和发数据的部分,这两部分需要同时执行,这就需要用到多线程了

     发送端:

/*
 * 编写一个聊天程序:
 * 分析:
 *         有接受数据的部分,和发数据的部分,这两部分需要同时执行,这就需要用到多线程了
 * */
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
/*
 * 发送端
 *     
 * */
public class UDP_Send_03 implements Runnable{
    private DatagramSocket ds;
    UDP_Send_03(DatagramSocket ds){
        this.ds=ds;
    }
    public void run() {
        try {
            ds=new DatagramSocket();
            Scanner sc=new Scanner(System.in);
            String line;
            while((line=sc.nextLine())!=null){
                if("886".equals(line))
                    break;
                byte by[]=line.getBytes();
                DatagramPacket dp=new DatagramPacket(by,by.length,InetAddress.getByName("127.0.0.1"),10110);
                ds.send(dp);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
}

接收端:

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

/*
 * 编写一个聊天程序:
 * 
 * 接受端
 * */
public class UDP_Rec_03 implements Runnable {
    private DatagramSocket ds;
    UDP_Rec_03(DatagramSocket ds){
        this.ds=ds;
    }
    public void run() {
        try {
            ds=new DatagramSocket(10110);
            
            while(true){
            byte by[]=new byte[1024];
            
            DatagramPacket  dp=new DatagramPacket(by,by.length);
            ds.receive(dp);
            String data=new String(dp.getData(),0,dp.getLength());
            
            System.out.println(data);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }
    //通过多线程的方式同时开启两个服务,这样就可以模拟聊天软件的环境进行交流了
    public static void main(String[] args) throws SocketException {
        DatagramSocket ds=new DatagramSocket();
        UDP_Rec_03 rec=new UDP_Rec_03(ds);
        UDP_Send_03 send=new UDP_Send_03(ds);
        new Thread(rec).start();
        new Thread(send).start();
                
    }
}

案例2:编写一个基于TCP的程序,完成客户端向服务器发送一段文字,服务器接收到后返回一段文字,客户端打印反馈的信息

客户端:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

/*
 * 文件复制,需求:将客户端的文件发到服务端,进行磁盘存储
 * */
public class CopyOfTCP_cli_04优化版 {
    public static void main(String[] args) throws UnknownHostException, IOException {
        Socket s=new Socket("127.0.0.1",10011);
        //获取输出流,将字节转化为字符,可以一次写一行数据
        PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
        //读取文件,用到了带缓冲的Reader,可以一次读取一行
        BufferedReader br=new BufferedReader(new FileReader("E:\a.txt"));
        String line=null;
        while((line=br.readLine())!=null){
            pw.println(line);
        }
        //文件发送完成,需要发送一个结束标记                要格外注意
        pw.println("over");  //或者使用s.shutdownOutput();
        
        BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));
        
        while((line=in.readLine())!=null)
        {
            System.out.println("服务器说:"+line);
        }
        br.close();
        in.close();
        pw.close();
        s.close();
                
    }
}

服务端:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class CopyOfTCP_ser_04优化版 {
    public static void main(String[] args) throws IOException {
        ServerSocket ss=new ServerSocket(10011);
        
        
        Socket s=ss.accept();
        //接受客户端发送的文件,用到了缓冲,并且将字节流转化为了字符流
        BufferedReader br =new BufferedReader(new InputStreamReader(s.getInputStream()));
        //向文件中写数据,用到了缓冲,可以写一行
        BufferedWriter bo=new BufferedWriter(new FileWriter("E:\BB.txt"));
        //向客户端写数据,用到了将字节流包装为Printwriter 从而可以将字节转化为字符串处理
        PrintWriter out=new PrintWriter(s.getOutputStream(),true);
        String line=null;
        while((line=br.readLine())!=null){
            if("over".equals(line))
                break;
            bo.write(line);
            bo.newLine();
            bo.flush();
        }
        out.println("文件收到");
        out.flush();
        s.close();
        
        
    }
}
原文地址:https://www.cnblogs.com/yueyazhishang/p/4059092.html