JavaSE基础自学-----网络编程

UDP----发送端/接收端

public class demo2 {
    //通过UDP协议完成一个聊天程序
    //一个负责发送,一个负责接收.两个任务需要同时进行
    //使用多线程技术

    public static void main(String[] args) throws UnknownHostException, SocketException {
        DatagramSocket send = new DatagramSocket();
        DatagramSocket rece = new DatagramSocket(20000);

        new Thread(new Send(send)).start();
        new Thread(new Rece(rece)).start();
    }
}

class Send implements Runnable {
    /*
     * 建立UDP发送端
     * 思路:
     * 1, 建立可以实现UDP传输的Socket服务
     * 2, 明确具体发送的数据
     * 3, 将数据封装成数据包
     * 4, 通过socket服务将具体数据发送出去
     * 5, 关闭服务
     * */

    private DatagramSocket ds;

    Send(DatagramSocket ds) {
        this.ds = ds;
    }

    @Override
    public void run() {
        //具体发送数据的任务内容

        //1, 要发送的数据来自哪里 键盘录入
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        //2, 将数据封装到数据包
        String line = null;
        try {
            while ((line = br.readLine()) != null) {

                byte[] bytes = line.getBytes();
                DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.1.7"), 20000);
                
              //3, 将数据包发送出去
                ds.send(dp);
                if (line.equals("over")) {
                    break;
                }
            }
            ds.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

//接收端
class Rece implements Runnable {
    private DatagramSocket ds;

    Rece(DatagramSocket ds) {
        this.ds = ds;
    }

    @Override
    public void run() {

        while (true) {
            byte[] bytes = new byte[1024];
            //创建数据包对象
            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);

            try {
                ds.receive(dp); //接收到的数据储存到数据包中

            } catch (IOException e) {
                e.printStackTrace();
            }

            //获取数据
            String ip = dp.getSocketAddress().toString();
            String str = new String(dp.getData(), 0, dp.getLength());//返回数据缓冲区
            System.out.println(ip + " : " + str);

            if (str.equals("over")) {
                System.out.println(ip + " -- 离开了~~~~~~");
            }
        }
    }
}

TCP----客户端/服务端

  • Socket和ServerSocket
    建立客户端和服务器端
    建立连接后,通过Socket中的IO流进行数据的传输
    关闭socket
    同样,客户端与服务器端是两个独立的应用程序。

客户端 Socket

  /*
         * TCP客户端建立
         * 思路:
         * 1, 建立TCP客户端socket服务,明确目的地址和端口
         * 2, 一旦连接建立, 就有了传输数据的通道,这个传输通道是通过IO流实现的,Socket IO流
         * 3, 只要获取Socket IO流,使用其中的写动作就可以将数据写到socket流中发送到服务端
         * 4, 关闭资源
         * */

        //客户端发送数据给服务端,并读取服务端反馈的数据
        //1, 创建Socket客户端 明确目的地址和端口
        System.out.println("客户端启动~~~~~~~~~");
        Socket socket = new Socket("192.168.1.7", 10080);

        //2, 获取socket流中的输出流,将数据发送到服务端
        OutputStream out = socket.getOutputStream();

        //3, 通过输出流写数据
        out.write("注意了,TCP客户端来了~~~~~~".getBytes());

        InputStream is = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int num = is.read(bytes);
        String str = new String(bytes, 0, num);
        System.out.println(str);

        //4, 关闭资源
        socket.close();

服务器端 ServerSocket

/*
         * 创建TCP服务器端
         * 思路:
         * 1, 创建Socket服务器端 ,服务器端为了能让客户端连接上,必须提供端口(监听一个端口)
         * 2, 获取客户端对象, 通过客户端的socket流和对应客户端进行通信
         * 3, 获取客户端socket流的读取流
         * 4, 读取数据,显示在服务器端
         * 5, 关闭资源
         * */

        System.out.println("服务器端启动~~~~~~~~~");

        //1, 创建客户端对象
        ServerSocket serverSocket = new ServerSocket(10080);

        //2, 获取客户端对象
        Socket socket = serverSocket.accept();//监听是否有客户端对象连接进来
        String ip = socket.getInetAddress().getCanonicalHostName();//获取IP地址

        //3, 通过客户端对象获取socket流的读取流
        InputStream is = socket.getInputStream();

        byte[] bytes = new byte[1024];
        int num = is.read(bytes);
        String str = new String(bytes, 0, num);
        System.out.println(ip + "  :   " + str);

        //4, 通过客户端对象获取socket流的输出对象
        OutputStream os = socket.getOutputStream();

        os.write("服务端收到了~~~~~~".getBytes());

        socket.close();
        serverSocket.close();

TCP上传文本示例------

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

        //客户端发送数据给服务端,并读取服务端反馈的数据

        // 创建Socket客户端 明确目的地址和端口
        System.out.println("客户端启动~~~~~~~~~");
        Socket socket = new Socket("192.168.1.7", 10080);

        //创建本地文件输入流
        BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\a.txt")));

        // 获取socket流中的输出流,将数据发送到服务端
        PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
//        OutputStream out = socket.getOutputStream();
//        BufferedWriter bfw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

        //频繁读写,将数据写到sock输出流中
        String line = null;
        while ((line = bfr.readLine()) != null) {
            pw.println(line);
        }

        //使用socket 的禁止输出流方法,向服务端发送停止标记
        socket.shutdownOutput();

        //获取socket流读取流,读取服务端反馈的信息
        BufferedReader bfrIN = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String string=null;
        while ((string=bfrIN.readLine())!=null){
            System.out.println(string);
        }
        
        // 关闭资源
        socket.close();
        bfr.close();
    }

---------------***********************************------------------
  public static void main(String[] args) throws IOException {

        System.out.println("服务器端启动~~~~~~~~~");

        //1, 创建服务端对象
        ServerSocket serverSocket = new ServerSocket(10080);

        //2, 获取客户端对象
        Socket socket = serverSocket.accept();
        String ip = socket.getInetAddress().getCanonicalHostName();

        //获取socket流中读取流
        BufferedReader bfrIN = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        //数据存储目的地
        PrintWriter pw = new PrintWriter(new FileWriter("E:\\aa.txt"), true);

        //频繁读写,将数据写到目的地
        String line = null;
        while ((line = bfrIN.readLine()) != null) {
            pw.println(line);
        }

        //向客户端发送反馈数据
        PrintWriter pwOut = new PrintWriter(socket.getOutputStream(), true);
        pwOut.print("上传成功 ");
        pwOut.flush();

        socket.close();
        serverSocket.close();
        pw.close();
    }

图片上传示例------解决重名,并发访问

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

        //客户端发送数据给服务端,并读取服务端反馈的数据

        // 创建Socket客户端 明确目的地址和端口
        System.out.println("客户端启动~~~~~~~~~");
        Socket socket = new Socket("192.168.1.7", 10080);

        //创建本地文件输入流
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream("E:\\1.jpg"));

        // 获取socket流中的输出流,将数据发送到服务端
        BufferedOutputStream bos=new BufferedOutputStream(socket.getOutputStream()); //使用缓冲区技术

        //频繁读写,将数据写到sock输出流中
        byte[] bytes=new byte[1024];
       int num=0;
       while ((num=bis.read(bytes))!=-1){
           bos.write(bytes,0,num);
           bos.flush();
       }

        //使用socket 的禁止输出流方法,向服务端发送停止标记
        socket.shutdownOutput();

        //获取socket流读取流,读取服务端反馈的信息
        BufferedReader bfrIN = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String string=null;
        while ((string=bfrIN.readLine())!=null){
            System.out.println(string);
        }

        // 关闭资源
        socket.close();
        bis.close();
    }

*********************************************************************
   public static void main(String[] args) throws IOException {
        System.out.println("服务器端启动~~~~~~~~~");
        // 创建服务端对象
        ServerSocket serverSocket = new ServerSocket(10080);

        while (true) {
            // 获取客户端对象
            Socket socket = serverSocket.accept();//监听是否有客户端对象连接进来

            new Thread(new picout(socket)).start(); //解决并发访问问题
        }   
}

class picout implements Runnable {
    private Socket socket;

    picout(Socket socket) {
        this.socket = socket;
    }
    
    @Override
    public void run() {
        try {
            String ip = socket.getInetAddress().getCanonicalHostName();
            System.out.println(ip + "--------连接到服务器");

            //获取socket流中读取流
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());

            //解决命名重复问题
            int count = 1;
            File dir = new File("E:\\pic");
            File file = new File(dir, ip + "(" + count + ").jpg");
            while (file.exists()) {
                count++;
                file = new File(dir, ip + "(" + count + ").jpg");
            }

            //数据存储目的地
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); //使用缓冲区技术

            //频繁读写,将数据写到目的地
            byte[] bytes = new byte[1024];
            int num = 0;
            while ((num = bis.read(bytes)) != -1) {
                bos.write(bytes, 0, num);
                bos.flush();
            }

            // 通过客户端对象获取socket流的输出对象,输出反馈信息
            PrintWriter pwOut = new PrintWriter(socket.getOutputStream(), true);
            pwOut.print("上传成功 ");
            pwOut.flush();

            socket.close(); //关闭资源
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

自定义服务器,浏览器给服务器发送的请求信息如下

Http协议请求头
GET / HTTP/1.1  //请求行
Accept: application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; Tablet PC 2.0)
UA-CPU: AMD64
Accept-Encoding: gzip, deflate
Host: 192.168.1.7:10080
Connection: Keep-Alive
*/
***********************************
服务端的应答信息

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept-Ranges: bytes
ETag: W/"48-1551884610418"
Last-Modified: Wed, 06 Mar 2019 15:03:30 GMT
Content-Type: text/html
Content-Length: 48
Date: Wed, 20 Mar 2019 04:11:37 GMT
Connection: close

URL对象

        String str_url = "http://192.168.1.7:8080/myweb/HTML1.html?name=lisi";

        URL url = new URL(str_url);
        System.out.println("Protocol : " + url.getProtocol());
        System.out.println("Host : " + url.getHost());
        System.out.println("Prot : " + url.getPort());
        System.out.println("Path : " + url.getPath());
        System.out.println("File : " + url.getFile());
        System.out.println("Query : " + url.getQuery());

        //通过url.openConnection(); 获取该远程资源的链接对象(内部封装了socket客户端)
        URLConnection uc=url.openConnection();
        System.out.println(uc);

        InputStream is=uc.getInputStream();
        byte[] bytes =new byte[1024];
        int num=is.read(bytes);
        String s=new String(bytes,0,num);
        System.out.println(s);
        System.out.println("得到反馈信息了");
        

网络架构

C/S Client Server

  • 特点:
    客户端和服务端都要编写
    客户端需要维护
    客户端可以分担部分运算
    如:大型运算,比如网络游戏

B/S Browser Server

  • 特点
    只需编写服务端,客户端就是已有的浏览器
    客户端不需要维护
    运算全在服务端
    如:网页游戏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值