java网络编程

一. 网络编程基本概念

  1. ISO(开放系统互联参考模型)七层协议模型

    1. 应用层
    2. 表示层
    3. 会话层
    4. 传输层
    5. 网络层
    6. 数据链路层
    7. 物理层
  2. b/s和c/s

    1. b/s:浏览器/服务器(公网访问)
    2. c/s:客户端/服务器(内网)
  3. TCP/IP参考模型

    1. 应用层(Telenet,FTP,SMTP,DNS,HTTP)
    2. 传输层(TCP/UDP)
    3. 网络层(IP)
    4. 物理+数据链路层
    • 应用层和传输层之间使用套接字(Socket)进行连接
  • TCP是面向连接的,传输数据安全,稳定,效率相对较低

    • 一种面向连接的,可靠的,基于字节流的运输层通信协议
    • 特点:
      • 面向连接
      • 点到点通信
      • 高可靠性
      • 占用系统资源多,效率低
  • UDP是面向无连接的,传输数据不安全,效率较高.

    • 一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务
    • 特点:
      • 非面向连接,传输不可靠,可能丢失
      • 发送不管对方是否准备好,接收方收到也不确认
      • 可以广播发送
      • 非常简单的协议,开销小
  1. TCP建立连接三部:

    1. 客户端发送syn(同步)报文,加原始的tcp连接序号
    2. 服务器接收到客户端的syn报文,返回syn+ack报文,同时tcp序号加一
    3. 客户端也返回一个ack报文给服务器,tcp序列化加一.
      • 三次握手完成
  2. 常用端口号(1024以下留给公用)

    1. 80:http
    2. 21:sftp
    3. 8080:tomcat
    4. 1521:oracle
    5. 3306:mysql
    6. 443:https

二. URL基本用法

  1. URI(Universal Resource Identifier)统一资源标识符

    1. URL(Universal Resource Locator)统一资源定位符
    2. URN(Universal Resource Name) 统一资源名称
  2. 爬虫基本原理

    package com.it;
    
    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    /**
     * 网络爬虫+模拟浏览器
     * @author ZRY
     * @version 1.0
     */
    public class SpiderTest02 {
        public static void main(String[] args) {
            try {
    //            URL url = new URL("https://www.jd.com");
                URL url = new URL("https://www.dianping.com");
                //下载资源
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setRequestProperty("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.34");
    //            InputStream is = url.openStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream(),"UTF-8"));
                String path = "Z://Desktop//11.txt";
                File file = new File(path);
                if (file.exists()){
                    file.delete();
                }
                String msg = null;
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                OutputStreamWriter outputStreamWriter =new OutputStreamWriter(fileOutputStream);
                BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);
    
                while (null!=(msg=bufferedReader.readLine())){
                    System.out.println(msg);
                    //写入文件
                    bufferedWriter.write(msg);
                    bufferedWriter.newLine();
                }
    
                bufferedReader.close();
                bufferedWriter.close();
            } catch (Exception e){
                e.printStackTrace();
            }
    
        }
    }
    

三. UDP编程

  1. 基本概念

    1. DatagramSocket:用于发送或者接收数据包的套接字
    2. DatagramPacket:数据包
  2. 客户端发送udp数据

    package com.it.udp;
    
    import com.sun.xml.internal.ws.wsdl.writer.document.http.Address;
    
    import javax.xml.crypto.Data;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    import java.net.SocketException;
    
    /**
     * 发送端
     *  * 1. 使用datagramSocket 指定端口 创建接收端
     *  * 2. 准备容器 封装成datagramPacket
     *  * 3. 阻塞式接收包裹receive
     *  * 4. 分析数据
     * @author ZRY
     * @version 1.0
     */
    public class UdpClient {
        public static void main(String[] args) {
            System.out.println("发送方启动中....");
            try {
                DatagramSocket client = new DatagramSocket(8888);
                String data = "你好,java";
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",9999));
                client.send(packet);
                //释放资源
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    
    
  3. 服务器接收udp数据

    package com.it.udp;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    /**
     * 接收端
     * 1. 使用datagramSocket 指定端口 创建接收端
     * 2. 准备容器 封装成datagramPacket
     * 3. 阻塞式接收包裹receive
     * 4. 分析数据
     * @author ZRY
     * @version 1.0
     */
    public class UdpServer {
        public static void main(String[] args) {
            System.out.println("接收方启动中...");
            try {
                DatagramSocket server = new DatagramSocket(9999);
                byte[] container = new byte[1024*60];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                server.receive(packet);
                byte[] datas = packet.getData();
                int len = packet.getLength();
                System.out.println("--"+new String(datas,0,len));
                server.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    
  4. 客户端通过UDP协议发送file文件

    package com.it.udp;
    
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    
    /**
     * 发送端
     *  * 1. 使用datagramSocket 指定端口 创建接收端
     *  * 2. 准备容器 封装成datagramPacket
     *  * 3. 阻塞式接收包裹receive
     *  * 4. 分析数据
     * @author ZRY
     * @version 1.0
     */
    public class UdpFileClient {
        public static void main(String[] args) {
            System.out.println("发送方启动中....");
            try {
                DatagramSocket client = new DatagramSocket(8888);
                //2.准备数据 转化为字节数组
                byte[] datas = IOFileUtils.byteArrayFile("src/img/1.jpg");
    
                DatagramPacket packet = new DatagramPacket(datas,datas.length,new InetSocketAddress("localhost",9999));
    
                client.send(packet);
                //释放资源
                client.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    
    
  5. 服务端通过UDP协议接收file文件

    package com.it.udp;
    
    import java.io.ByteArrayInputStream;
    import java.io.DataInputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * 接收端
     * 1. 使用datagramSocket 指定端口 创建接收端
     * 2. 准备容器 封装成datagramPacket
     * 3. 阻塞式接收包裹receive
     * 4. 分析数据
     * 5. 将字节数组还原为基本数据类型
     * @author ZRY
     * @version 1.0
     */
    public class UdpFileServer {
        public static void main(String[] args) {
            System.out.println("接收方启动中...");
            try {
                DatagramSocket server = new DatagramSocket(9999);
                //准备容器
                byte[] container = new byte[1024*60];
                DatagramPacket packet = new DatagramPacket(container,container.length);
                //阻塞式接收数据
                server.receive(packet);
                //分析数据
                byte[] datas = packet.getData();
                int len = packet.getLength();
                IOFileUtils.byteArrayToFile(datas,"src/img/1-1.jpg");
    
                server.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    
  6. 文件转化字节数组工具

    package com.it.udp;
    
    import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;
    
    import java.io.*;
    
    /**
     * @author ZRY
     * @version 1.0
     */
    public class IOFileUtils {
        /**
         * 将文件转化为字节数组
         * @param filepath
         * @return
         */
        public static byte[] byteArrayFile(String filepath){
            //1.创建源于目的地
            File file = new File(filepath);
            byte[] dest= null;
            //2.选择流
            InputStream is =null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream((int) file.length());
            try {
                is=new FileInputStream(file);
                baos = new ByteArrayOutputStream();
                dest = new byte[1024*60];
                int len = 0;
                while ((len=is.read(dest))!=-1){
                    baos.write(dest,0,len);
                }
                return baos.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (is!=null){
                        is.close();
                    }
                    if (baos!=null){
                        baos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        public static void byteArrayToFile(byte[] src,String filepath){
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(new File(filepath));
                fileOutputStream.write(src,0,src.length);
                System.out.println("保存成功...");
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    if (fileOutputStream!=null){
                        fileOutputStream.close();
                    }
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
    }
    
    
  7. 客户端通过UDP协议发送基本数据类型

    package com.it.udp;
    
    import com.sun.corba.se.impl.oa.poa.AOMEntry;
    
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetSocketAddress;
    
    /**
     * 发送端
     *  * 1. 使用datagramSocket 指定端口 创建接收端
     *  * 2. 准备容器 封装成datagramPacket
     *  * 3. 阻塞式接收包裹receive
     *  * 4. 分析数据
     * @author ZRY
     * @version 1.0
     */
    public class UdpTypeClient {
        public static void main(String[] args) {
            System.out.println("发送方启动中....");
            try {
                DatagramSocket client = new DatagramSocket(8888);
                ByteArrayOutputStream bs = new ByteArrayOutputStream();
    
                DataOutputStream ds = new DataOutputStream(new BufferedOutputStream(bs));
                ds.writeUTF("你好,java");
                ds.writeInt(18);
                ds.writeChar('v');
                ds.writeBoolean(false);
                ds.flush();
                System.out.println("bs="+bs);
                System.out.println("ds="+ds);
                byte[] datas = bs.toByteArray();
    
                System.out.println("==="+datas);
                System.out.println("=="+datas.length);
    
                DatagramPacket packet = new DatagramPacket(datas,datas.length,new InetSocketAddress("localhost",9999));
    
                client.send(packet);
                //释放资源
                client.close();
                bs.close();
                ds.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    }
    
    
  8. 服务器通过UDP协议接收基本数据类型

    package com.it.udp;
    
    import java.io.BufferedInputStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataInputStream;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * 接收端
     * 1. 使用datagramSocket 指定端口 创建接收端
     * 2. 准备容器 封装成datagramPacket
     * 3. 阻塞式接收包裹receive
     * 4. 分析数据
     * 5. 将字节数组还原为基本数据类型
     * @author ZRY
     * @version 1.0
     */
    public class UdpTypeServer {
        public static void main(String[] args) {
            System.out.println("接收方启动中...");
            try {
                DatagramSocket server = new DatagramSocket(9999);
                byte[] container = new byte[1024*60];
                DatagramPacket packet = new DatagramPacket(container,container.length);
                server.receive(packet);
    
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(packet.getData());
                DataInputStream dataInputStream = new DataInputStream(byteArrayInputStream);
                String msg = dataInputStream.readUTF();
                int age = dataInputStream.readInt();
                char ch = dataInputStream.readChar();
                boolean flag = dataInputStream.readBoolean();
                System.out.println("age="+age);
                System.out.println("msg="+msg);
                System.out.println("flag="+flag);
                System.out.println("ch="+ch);
                server.close();
                dataInputStream.close();
                byteArrayInputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

四. 聊天窗

服务端

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author ZRY
 * @version 1.0
 */
public class Server extends JFrame implements ActionListener, KeyListener {
    /**
     * 启动方法
     * @param args
     */
    public static void main(String[] args) throws Exception{
//        UIManager.setLookAndFeel("org.jb2011.lnf.beautyeye.BeautyEyeLookAndFeelCross");
        new Server();
    }
    private JScrollPane jScrollPane;//窗口,视图
    private JTextField jTextField;//单行文本
    private JPanel jPanel;//面板
    private JTextArea jTextArea;//文本区域
    private JButton jButton;//按钮
    private BufferedWriter bufferedWriter=null;//输出流
    public Server(){
        myFrame(this);
        figen();
    }
    /**
     * Invoked when an action occurs.
     *
     * @param e
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        JFprint();
    }

    /**
     * Invoked when a key has been typed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key typed event.
     *
     * @param e
     */
    @Override
    public void keyTyped(KeyEvent e) {

    }

    /**
     * Invoked when a key has been pressed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key pressed event.
     *
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode()==KeyEvent.VK_ENTER){
            JFprint();
        }
    }

    /**
     * Invoked when a key has been released.
     * See the class description for {@link KeyEvent} for a definition of
     * a key released event.
     *
     * @param e
     */
    @Override
    public void keyReleased(KeyEvent e) {

    }
    /**
     * 在客户端的聊天窗新增内容
     */
    public void JFprint(){
        //获取输入框内容
        String text = jTextField.getText();
        text="服务端:\t"+text;
        //System.lineSeparator()  ===>   \n\r
        jTextArea.append(text+System.lineSeparator());
        try {
            bufferedWriter.write(text);
            bufferedWriter.newLine();
            bufferedWriter.flush();
            //置空
            jTextField.setText("");
        }catch (IOException e){
            e.printStackTrace();
        }

    }
    /**
     * 发送内容给服务器
     */
    public void figen(){
        try {
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket socket = serverSocket.accept();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String line = null;
            Date date=new Date();
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat();
//            simpleDateFormat.format(date);
            //在文本区域生成时间
            jTextArea.append("\t"+ simpleDateFormat.format(date)+"\n");
            while ((line=bufferedReader.readLine())!=null){
                jTextArea.append(line+System.lineSeparator());
            }
            socket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 客户端窗口
     * @param server
     */
    public void myFrame(Server server){
        //初始化面板
        jPanel = new JPanel();
        //初始化按钮
        jButton=new JButton("发送");
        //初始化输入框
        jTextField = new JTextField(10);
        //初始化文本区域
        jTextArea =new JTextArea();
        jTextArea.setEditable(false);
        //初始化窗口
        jScrollPane = new JScrollPane(jTextArea);
        jPanel.add(jTextField);
        jPanel.add(jButton);
        //在当前对象的南面添加面板区域,包括输入框和按钮
        server.add(jPanel, BorderLayout.SOUTH);
        //在当前对象的中间添加文本区域
        server.add(jScrollPane,BorderLayout.CENTER);
        //初始化程序标题
        server.setTitle("小同学");
        //初始化大小
        server.setSize(300,500);
        //初始化位置
        server.setLocation(500,300);
        //使窗口位于屏幕中央
        server.setLocationRelativeTo(null);
        //
        server.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //显示
        server.setVisible(true);
        jButton.addActionListener(server);
        jTextField.addKeyListener(server);

    }
}

客户端

import javax.swing.*;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.*;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author ZRY
 * @version 1.0
 */
public class Client extends JFrame implements ActionListener, KeyListener {
    private JScrollPane jScrollPane;//窗口,视图
    private JTextField jTextField;//单行文本
    private JPanel jPanel;//面板
    private JTextArea jTextArea;//文本区域
    private JButton jButton;//按钮
    private BufferedWriter bufferedWriter=null;//输出流
    public  Client(){
        myFrame(this);
        figen();

    }
    /**
     * 启动方法
     * @param args
     */
    public static void main(String[] args) throws Exception{
//        UIManager.setLookAndFeel("org.jb2011.lnf.beautyeye.BeautyEyeLookAndFeelCross");
        new Client();
    }

    /**
     * Invoked when an action occurs.
     *
     * @param e
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        JFprint();
        figen();
    }

    /**
     * Invoked when a key has been typed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key typed event.
     *
     * @param e
     */
    @Override
    public void keyTyped(KeyEvent e) {

    }

    /**
     * Invoked when a key has been pressed.
     * See the class description for {@link KeyEvent} for a definition of
     * a key pressed event.
     *
     * @param e
     */
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode()== KeyEvent.VK_ENTER){
            JFprint();
        }

    }

    /**
     * Invoked when a key has been released.
     * See the class description for {@link KeyEvent} for a definition of
     * a key released event.
     *
     * @param e
     */
    @Override
    public void keyReleased(KeyEvent e) {

    }

    /**
     * 在客户端的聊天窗新增内容
     */
    public void JFprint(){
        //获取输入框内容
        String text = jTextField.getText();
        text="客户端:\t"+text;
        //System.lineSeparator()  ===>   \n\r
        jTextArea.append(text+System.lineSeparator());
        try {
            bufferedWriter.write(text);
            bufferedWriter.newLine();
            bufferedWriter.flush();
            //置空
            jTextField.setText("");
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    /**
     * 发送内容给服务器
     */
    public void figen(){
        try {
            Socket socket=new Socket("localhost",8888);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            bufferedWriter=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String line = null;
            Date date=new Date();
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat();
//            simpleDateFormat.format(date);
            //在文本区域生成时间
            jTextArea.append("\t"+ simpleDateFormat.format(date)+"\n");
            while ((line=bufferedReader.readLine())!=null){
                jTextArea.append(line+System.lineSeparator());
            }
            socket.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 客户端窗口
     * @param client
     */
    public void myFrame(Client client){
        //初始化面板
        jPanel = new JPanel();
        //初始化按钮
        jButton=new JButton("发送");
        //初始化输入框
        jTextField = new JTextField(10);
        //初始化文本区域
        jTextArea =new JTextArea();
        jTextArea.setEditable(false);
        //初始化窗口
        jScrollPane = new JScrollPane(jTextArea);
        jPanel.add(jTextField);
        jPanel.add(jButton);
        //在当前对象的南面添加面板区域,包括输入框和按钮
        client.add(jPanel, BorderLayout.SOUTH);
        //在当前对象的中间添加文本区域
        client.add(jScrollPane,BorderLayout.CENTER);
        //初始化程序标题
        client.setTitle("小同学");
        //初始化大小
        client.setSize(300,500);
        //初始化位置
        client.setLocation(500,300);
        //使窗口位于屏幕中央
        client.setLocationRelativeTo(null);
        //
        client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //显示
        client.setVisible(true);
        jButton.addActionListener(client);
        jTextField.addKeyListener(client);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值