网络编程

网络编程

软件结构
C/S 和 B/S
网络通信协议
协议就是个规则
网络通信协议的分类
UDP TCP/IP
端口号在这里插入图片描述
TCP通信
在这里插入图片描述
TCP通信的客户端代码实现

package com.itheima.demo01.TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/* TCP通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据 表示客户端的类: java.net.Socket:此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点。 套接字:包含了IP地址和端口号的网络单位 构造方法: Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。 参数: String host:服务器主机的名称/服务器的IP地址 int port:服务器的端口号 成员方法: OutputStream getOutputStream() 返回此套接字的输出流。 InputStream getInputStream() 返回此套接字的输入流。 void close() 关闭此套接字。 实现步骤: 1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号 2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象 3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据 4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象 5.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据 6.释放资源(Socket) 注意: 1.客户端和服务器端进行交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象 2.当我们创建客户端对象Socket的时候,就会去请求服务器和服务器经过3次握手建立连接通路 这时如果服务器没有启动,那么就会抛出异常ConnectException: Connection refused: connect 如果服务器已经启动,那么就可以进行交互了 */
public class TCPClient {
   
    public static void main(String[] args) throws IOException {
   
        //1.创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号
        Socket socket = new Socket("127.0.0.1",8888);
        //2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
        os.write("你好服务器".getBytes());

        //4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();

        //5.使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println(new String(bytes,0,len));

        //6.释放资源(Socket)
        socket.close();

    }

}

TCP通信的服务器端代码实现

package com.itheima.demo01.TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/* TCP通信的服务器端:接收客户端的请求,读取客户端发送的数据,给客户端回写数据 表示服务器的类: java.net.ServerSocket:此类实现服务器套接字。 构造方法: ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 服务器端必须明确一件事情,必须的知道是哪个客户端请求的服务器 所以可以使用accept方法获取到请求的客户端对象Socket 成员方法: Socket accept() 侦听并接受到此套接字的连接。 服务器的实现步骤: 1.创建服务器ServerSocket对象和系统要指定的端口号 2.使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket 3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象 4.使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据 5.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象 6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据 7.释放资源(Socket,ServerSocket) */
public class TCPServer {
   
    public static void main(String[] args) throws IOException {
   
        //1.创建服务器ServerSocket对象和系统要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        //2.使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket
        Socket socket = server.accept();
        //3.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //4.使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println(new String(bytes,0,len));
        //5.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //6.使用网络字节输出流OutputStream对象中的方法write,给客户端回写数据
        os.write("收到谢谢".getBytes());
        //7.释放资源(Socket,ServerSocket)
        socket.close();
        server.close();
    }
}

综合案例_文件上传的原理
在这里插入图片描述
文件上传案例的客户端和服务器端

/* 文件上传案例的客户端:读取本地文件,上传到服务器,读取服务器回写的数据 明确: 数据源:c:\\1.jpg 目的地:服务器 实现步骤: 1.创建一个本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源 2.创建一个客户端Socket对象,构造方法中绑定服务器的IP地址和端口号 3.使用Socket中的方法getOutputStream,获取网络字节输出流OutputStream对象 4.使用本地字节输入流FileInputStream对象中的方法read,读取本地文件 5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传到服务器 6.使用Socket中的方法getInputStream,获取网络字节输入流InputStream对象 7.使用网络字节输入流InputStream对象中的方法read读取服务回写的数据 8.释放资源(FileInputStream,Socket) */
 
 package com.itheima.demo02.FileUpload;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient {
   
    public static void main(String[] args) throws IOException {
   
        FileInputStream fis = new FileInputStream("11_Net\\1.jpg");
        Socket socket = new Socket("192.168.1.106",8888);
        OutputStream outputStream = socket.getOutputStream();

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!=-1){
   
            outputStream.write(bytes,0,len);
        }

        InputStream inputStream = socket.getInputStream();
        while((len = inputStream.read())!=-1){
   
            System.out.println(new String(bytes,0,len));
        }

        fis.close();
        socket.close();

    }
}
/* 文件上传案例服务器端:读取客户端上传的文件,保存到服务器的硬盘,给客户端回写"上传成功" 明确: 数据源:客户端上传的文件 目的地:服务器的硬盘 d:\\upload\\1.jpg 实现步骤: 1.创建一个服务器ServerSocket对象,和系统要指定的端口号 2.使用ServerSocket对象中的方法accept,获取到请求的客户端Socket对象 3.使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象 4.判断d:\\upload文件夹是否存在,不存在则创建 5.创建一个本地字节输出流FileOutputStream对象,构造方法中绑定要输出的目的地 6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件 7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上 8.使用Socket对象中的方法getOutputStream,获取到网络字节输出流OutputStream对象 9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功" 10.释放资源(FileOutputStream,Socket,ServerSocket) */
package com.itheima.demo02.FileUpload;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
   
    public static void main(String[] args) throws IOException {
   
        ServerSocket server = new ServerSocket(8888);
        Socket socket = server.accept();
        InputStream is = socket.getInputStream();
        File file = new File("d:\\upload");
        if(!file.exists()){
   
            file.mkdir();
        }
        FileOutputStream fos = new FileOutputStream(file+"\\1.jpg");

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = is.read(bytes))!=-1){
   
            fos.write(bytes,0,len);
        }

        OutputStream os = socket.getOutputStream();
        os.write("上传成功".getBytes());

        fos.close();
        socket.close();
        server.close();
    }
}

综合案例_文件上传案例阻塞问题
在这里插入图片描述
客户端改下

package com.itheima.demo02.FileUpload;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class TCPClient {
   
    public static void main(String[] args) throws IOException {
   
        FileInputStream fis = new FileInputStream("11_Net\\1.jpg");
        Socket socket = new Socket("192.168.1.106",8888);
        OutputStream outputStream = socket.getOutputStream();

        int len = 0;
        byte[] bytes = new byte[1024];
        while((len = fis.read(bytes))!=-1){
   
            outputStream.write(bytes,0,len);
        }
        socket.shutdownOutput();

        InputStream inputStream = socket.getInputStream();
        while((len = inputStream.read(bytes))!=-1){
   
            System.out.println(new String(bytes,0,len));
        }

        fis.close();
        socket.close();

    }
}

综合案例_文件上传案例优化(文件命名&循环接收&多线程提高效率)
服务器端的改进

package com.itheima.demo03.FileUpload;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

public class TCPServer {
   
    public static void main(String[] args) throws IOException {
   
        ServerSocket server = new ServerSocket(8888);
        while (true) {
   
            Socket socket = server.accept();

            new Thread(new Runnable() {
   
                @Override
                public void run() {
   
                    try{
   
                        InputStream is = socket.getInputStream();
                        File file = new File("d:\\upload");
                        if (!file.exists()) {
   
                            file.mkdir();
                        }

                        String fileName ="itcast"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";
                        FileOutputStream fos = new FileOutputStream(file + "\\"+fileName);

                        int len = 0;
                        byte[] bytes = new byte[1024];
                        while ((len = is.read(bytes)) != -1) {
   
                            fos.write(bytes, 0, len);
                        }

                        OutputStream os = socket.getOutputStream();
                        os.write("上传成功".getBytes());

                        fos.close();
                        socket.close();

                    }catch (IOException e){
   
                        System.out.println(e);
                    }
                }
            }).start();
            //server.close();
        }
    }
}

模拟BS服务器分析
在这里插入图片描述

package com.itheima.demo04.BSTCP;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/* 创建BS版本TCP服务器 */
public class TCPServerThread {
   
    public static void main(String[] args) throws IOException {
   
        //创建一个服务器ServerSocket,和系统要指定的端口号
        ServerSocket server = new ServerSocket(8080);

        /* 浏览器解析服务器回写的html页面,页面中如果有图片,那么浏览器就会单独的开启一个线程,读取服务器的图片 我们就的让服务器一直处于监听状态,客户端请求一次,服务器就回写一次 */
        while(true){
   
            //使用accept方法获取到请求的客户端对象(浏览器)
            Socket socket = server.accept();

            new Thread(new Runnable() {
   
                @Override
                public void run() {
   
                    try {
   
                        //使用Socket对象中的方法getInputStream,获取到网络字节输入流InputStream对象
                        InputStream is = socket.getInputStream();
                        //使用网络字节输入流InputStream对象中的方法read读取客户端的请求信息
                        /*byte[] bytes = new byte[1024]; int len = 0; while((len = is.read(bytes))!=-1){ System.out.println(new String(bytes,0,len)); }*/

                        //把is网络字节输入流对象,转换为字符缓冲输入流
                        BufferedReader br = new BufferedReader(new InputStreamReader(is));
                        //把客户端请求信息的第一行读取出来 GET /11_Net/web/index.html HTTP/1.1
                        String line = br.readLine();
                        System.out.println(line);
                        //把读取的信息进行切割,只要中间部分 /11_Net/web/index.html
                        String[] arr = line.split(" ");
                        //把路径前边的/去掉,进行截取 11_Net/web/index.html
                        String htmlpath = arr[1].substring(1);

                        //创建一个本地字节输入流,构造方法中绑定要读取的html路径
                        FileInputStream fis = new FileInputStream(htmlpath);
                        //使用Socket中的方法getOutputStream获取网络字节输出流OutputStream对象
                        OutputStream os = socket.getOutputStream();

                        // 写入HTTP协议响应头,固定写法
                        os.write("HTTP/1.1 200 OK\r\n".getBytes());
                        os.write("Content-Type:text/html\r\n".getBytes());
                        // 必须要写入空行,否则浏览器不解析
                        os.write("\r\n".getBytes());

                        //一读一写复制文件,把服务读取的html文件回写到客户端
                        int len = 0;
                        byte[] bytes = new byte[1024];
                        while((len = fis.read(bytes))!=-1){
   
                            os.write(bytes,0,len);
                        }

                        //释放资源
                        fis.close();
                        socket.close();
                    }catch (IOException e){
   
                        e.printStackTrace();
                    }
                }
            }).start();


        }


        //server.close();
    }
}

浏览器充当客户端,输入网址:http://192.168.1.106:8080/11_Net/web/index.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100188.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • anycast隧道_讲述IPv6网络中的选播概述及Anycast困难解决方法

    anycast隧道_讲述IPv6网络中的选播概述及Anycast困难解决方法APanoramaofAnycastinIPv6NetworksSUNFei,LIZhi-tang,LIYao(NetworkCentre,HuazhongUniversityofScienceandTecnology,Wuhan430074)Abstract:Anycastisanew“one-to-one-of-many”communicati…

  • java Calendar获取当前时间

    java Calendar获取当前时间获取系统当前时间戳 publicstaticvoidmain(String[]args){ Calendarcal=Calendar.getInstance(); intyear=cal.get(Calendar.YEAR); intmonth=cal.get(Calendar.MONTH)+1; intday=cal.get(Calendar….

  • EJB学习心得

    EJB学习心得注意:在EJB中对Bean的定位是通过JNDI的名称来确定的一:当EJB发布到JBOSS时,如果我们没有为它指定全局JNDI名称或修改其默认的EJB名称, JBOSS就会按照默认的命名规则为EJB生成全局JNDI名称。默认的命名规则如下: 如果把EJB作为模块打包进后缀*.ear的JAVAEE企业应用文件,默认的全局JNDI名称是  本地接口:EAR-FILE-BASE-NAME/EJB-C…

  • Tesseract-OCR引擎 入门

    OCR(OpticalCharacterRecognition):光学字符识别,是指对图片文件中的文字进行分析识别,获取的过程。Tesseract:开源的OCR识别引擎,初期Tesseract引

    2021年12月22日
  • mbus接口电路_数据总线

    mbus接口电路_数据总线本文来自我的163博客搬移春节放假前到现在,设计了一款采集器,采集器的设计按照标准的MBUS协议设计,设计容量为最大可同时对100只水表的水量数据进行采集。硬件设计:原理图设计上采用自顶向下的分层电路图设计方法,分为5个电路子图,分别为单片机小系统部分、电源部分、MBUS协议部分、短路保护部分、通信部分。1、单片机小系统部分的设计上将编程引脚的时钟和…

    2022年10月16日
  • VS2017 安装 Microsoft Visual Studio Installer Project

    VS2017 安装 Microsoft Visual Studio Installer Project1.安装打包插件:MicrosoftVisualStudio2017安装程序项目2.联机查找下面的组件,然后安装,重启VS,进行插件安装3.新建安装项目,另外,有些人可能会想这么多安装类型,怎么选。因为我们这里说的Windows程序打包,输出文件格式为.exe或者.msi,大概看一下介绍就能知道,第一个和第四个是合适的。这两个又该怎么选呢?那其实第四个就是对一些属性多了些引导,最…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号