TCP、B\S Socket网络编程案例详解

1 TCP

1.1 TCP通信概述

TCP:面向连接的协议(3次握手)

  • 客户端---->服务端–>客户端向服务端请求连接
  • 客户端<----服务端–>服务端告诉客户端可以连接
  • 客户端---->服务端–>客户端直接连接服务端

特殊地址:

  • 127.0.0.1–>代表的本机ip 我自己
  • localhost

端口号:是每一个应用程序的唯一标识范围0-65535 前1024已经被占用

1.2 实现简单客户端和服务端的交互

编写客户端
客户端
  Socket
  构造:
     Socket​(String host, int port)
            host:连接服务端的ip地址
                 自己的计算机做服务器:127.0.0.1(localhost)
            port:服务器设置的端口号
  步骤:
     1.创建Socket对象,指定要连接的服务器ip以及服务器设置的端口号
     2.调用Socket中的getOutputStream获取OutputStream,往服务器上发请求(写数据)
     3.调用Socket中国的getInputStream,读取服务端响应回来的结果(读数据)
     4.关流

/**
 * 编写客户端
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        InputStream is = null;
        //创建客户端对象
        try {
            socket = new Socket("127.0.0.1",8888);
            //调用Socket中的getOutputStream方法往服务端写请求(写数据)
            os = socket.getOutputStream();
            os.write("我想要一个看小视频的网站".getBytes());
            //调用getInputStream读取服务端响应的结果(读数据)
            is = socket.getInputStream();
            //创建字节数组
            byte[]bytes = new byte[1024];
            //因为只读一条数据,不用while循环了
            int read = is.read(bytes);
            System.out.println("==========服务端响应的结果=========");
            System.out.println(new String(bytes,0,read));
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //关流
            try {
                if(os != null && is != null && socket != null){
                    os.close();
                    is.close();
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}
编写服务端
服务端:ServerSocket:
        构造:
          ServerSocket​(int port)
              port:是服务器设置的端口号

        方法:
           Socket accept()-->等待接收连接服务端的客户端对象
                             那个客户端连接我这个服务端,此
                             方法返回的Socket对象就是哪个
                             客户端的Socket对象
        步骤:
           1.创建ServerSoceket,设置自己的端口号
           2.调用accept方法获取连接服务端的客户端对象
           3.调用getInputStream用来读取客户端发来的请求数据(读数据)
           4.调用getOutputStream往客户端响应一条数据(写数据)
           5.关闭资源

public class Server {
    public static void main(String[] args) throws Exception{
        //创建服务端对象,设置自己的端口号:要和客户端传过来的一致
        ServerSocket serverSocket = new ServerSocket(8888);
        //调用accept方法获取客户端对象
        Socket accept = serverSocket.accept();
        //获取客户端传过来的数据
        InputStream is = accept.getInputStream();
        //读取:
        byte[]bytes = new byte[1024];
        int read = is.read(bytes);
        System.out.println("============这是客户端传过来的数据=============");
        System.out.println(new String(bytes,0,read));

        //服务端响应
        OutputStream os = accept.getOutputStream();
        os.write("给你一个小视频:".getBytes());
        //关闭资源
        os.close();
        is.close();
        accept.close();
        serverSocket.close();
    }
}

1.3 文件上传

客户端
 客户端:
 步骤:
    1.创建Socket对象,指定服务端的ip以及端口号
    2.创建FileInputStream用于读取硬盘上的图片
    3.调用getOutputStream用于往服务端写我们读到的图片
    4.边读边写
    5.调用getInputStream.接收服务端响应回来的结果
    6.关闭资源

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) throws Exception{
        //创建Socket对象,设置服务端的ip及端口号
        Socket socket = new Socket("127.0.0.1", 6666);
        //创建FileInputStream读取本地图片
        FileInputStream fis = new FileInputStream("D:\\test1\\2.jpg");
        //创建socket中的getOutStream往服务器端写读到的图片
        OutputStream os = socket.getOutputStream();

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

        //通知服务器端.当读到-1的时候不写数据了,让服务器端继续往下执行
        socket.shutdownOutput();
        System.out.println("------------以下是接收服务端响应回来的结果-----------");
        //调用getInputStream读取服务端响应的数据
        InputStream is = socket.getInputStream();
        //遍历
        byte[]bytes1 = new byte[1024];
        int len1 = is.read(bytes1);
        System.out.println(new String(bytes1,0,len1));
        //6.关闭资源
        is.close();
        os.close();
        fis.close();
        socket.close();
    }
}
服务端
  服务端:
  步骤:
     1.创建ServerSocket对象,设置端口号
     2.调用accept方法,等待接收连接过来的客户端对象
     3.调用getInputStream.读取客户端歇过来的图片
     4.创建FileOutputStream对象,往硬盘上的指定位置写图片数据
     5.边读边写
     6.调用getOputStream往客户端写数据->响应一个"文件上传成功"
     7.关闭资源

   异常:Address already in use: JVM_Bind:连续来了2次服务器(端口号被占用)

/**
 * 服务端
 */
public class Server {
    public static void main(String[] args) throws Exception{
        //读取客户端传输过来的数据
        ServerSocket serverSocket = new ServerSocket(6666);

        //多线程
        while (true){
            new Thread(()->{
                Socket accept = null;
                InputStream is = null;
                FileOutputStream fos = null;
                OutputStream os = null;
                try{
                    //和客户端建立连接
                    accept = serverSocket.accept();
                    //读取数据
                    is = accept.getInputStream();
                    //复制多个图片,防止覆盖
                    String name = System.currentTimeMillis() + new Random().nextInt(10000) + ".jpg";
                    //创建FileOutputStream往指定路径复制图片信息
                    fos = new FileOutputStream("D:\\test\\"+name);

                    //边读边写
                    byte[]bytes = new byte[1024];
                    int len = 0;
                    while ((len=is.read(bytes))!=-1){
                        fos.write(bytes,0,len);
                    }
                    System.out.println("----------以下是往客户端响应的结果----------");
                    //调用getOutStream往客户端响应一个结果
                    os = accept.getOutputStream();
                    os.write("复制成功".getBytes());

                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    //关流
                    try {
                        if(os != null && fos != null && is != null && accept != null){
                            os.close();
                            fos.close();
                            is.close();
                            accept.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

            }).start();
        }

    }
}

2 模拟B\S服务器

模拟网站服务器,使用浏览器访问自己编写的服务端程序,查看网页效果。

案例分析

  1. 准备页面数据,web文件夹。
  2. 我们模拟服务器端,ServerSocket类监听端口,使用浏览器访问,查看网页效果

案例实现


public class BS_Server {
    public static void main(String[] args) throws Exception{
        //创建ServerSocket对象,指定端口号
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true){
            new Thread(() ->{
                try{
                    //获取客户端对象
                    Socket accept = serverSocket.accept();
                    //调用getInputStream获取浏览器发过来的请求
                    InputStream is = accept.getInputStream();
                    //创建BufferedReader对象
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    //读取第一行
                    String s = br.readLine();
                    //处理字符串想办法得到day/web/index.html
                    String[] s1 = s.split(" ");
                    String s2 = s1[1];
                    String substring = s2.substring(1);
                    //创建FileInputStream读取本地的页面
                    FileInputStream fis = new FileInputStream(substring);
                    //调用getOutputStream,往客户端响应页面
                    OutputStream os = accept.getOutputStream();
                    os.write("HTTP/1.1 200 OK\r\n".getBytes());//响应行
                    os.write("Content-Type:text/html\r\n".getBytes());//响应头
                    os.write("\r\n".getBytes());

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

                    //关流
                    os.close();
                    fis.close();
                    br.close();
                    is.close();
                    accept.close();
                }catch (Exception e){
                    e.printStackTrace();
                }

            }).start();
        }

    }
}

然后在浏览器输入http://localhost:8888/day18/web/index.html就会出效果了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值