韩顺平Java自学笔记 网络多线程

发布于:2023-01-12 ⋅ 阅读:(413) ⋅ 点赞:(0)

目录

一。网络的相关概念

1.网络的分类

 2.ip地址

 3.域名和端口号

 4.网络通信协议

5.tcp和udp协议

 6.重要的方法

二.Socket网络编程

1.使用字节流的形式

 2.依旧是字节流案例

3.案例三,使用字符流

4.使用字符流传递图片

5.netstat指令

 三。通信协议的理解

1。tcp协议的一个小秘密

2.UDP网络编程(了解)

四。课后的作业

1。作业一

2.课后作业二

 3.课后作业三


一。网络的相关概念

1.网络的分类

根据网络覆盖的范围来区分,中国大陆地区就是一个特别大的局域网

 2.ip地址

由于连入联网的设备扩展了(万物互联的概念),由单纯计算机主机可以联网,扩展到了手机,手表,电视等都可以。ipv4的地址不够用,所以扩展出了ipv6。 八个二进制位为一个字节,ipv4占用四个字节,ipv6站十六个字节。

 服务器的ip地址是固定的,一般电脑上网的ip地址是不固定的 。

 3.域名和端口号

因为ip地址不好记忆,所以就用域名代替了ip地址,ip与域名的转换是遵守dns规则的。

如果把你的电脑想成一个客栈,他会有很多的门,不同的门对应不同的服务,别的主机传送来的消息,都会从你的门来给你传入。客栈的门就相当于电脑的端口。

访问网站,是以端口+服务的形式来实现网站的访问的。

端口号一共占有两个字节。 

 一个端口只能绑定一个服务。端口只与网络服务有关。

 4.网络通信协议

先拿人与人之间的交流做比较,语言可以说是一种协议(规范)不遵守,对方就听不懂了。网络之间的信息传输也遵循着一套协议。消息经过固定的格式打包,就像是语言交流当中的语法。(简单解释)

数据封装的过程

 像是快递,要有打包的过程,只有打包过后的程序,才能发送。这是打包,用户解析是反过来的。

数据的解析形式就是协议,协议,把信息准确无误的发送给对方。计算机之间相互沟通的行为规范。

网络通信协议模型

 主要是tcp模型,osi模型太细,区分太细没有意义。

tcp和ip协议是最基础的信息协议,链路是用来增加帧头和帧尾的。如果我们设置 一个信息包的发送,识别规则,那他是建立在tcp,ip协议的基础之上的。

5.tcp和udp协议

传输层两个协议的区别。

tcp:可靠,量大,效率低。

你人比喻模拟

两人打电话,打通了之后,要先确认双方到底能不能互相正确的接收到信息。A说你好之后,B回你好之后,在说明要说事情了,才能确保通话正常。

一班传送数据文件音频。

 udp:不可靠,量小,但是速度快。

直接将信息发送给你,不管你接收不接收,发送给你之后就完事了。

 6.重要的方法

InetAdress当中的一些方法

package com.api;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class API_ {
    public static void main(String[] args) throws UnknownHostException {
//        获得本机的InetAddress对象
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);
//      根据指定的主机名获得InetAddress对象
        InetAddress byName = InetAddress.getByName("LAPTOP-D83EFCRR");
        System.out.println(byName);
//      根据域名返回对应的ip
        InetAddress byName1 = InetAddress.getByName("www.baidu.com");
        System.out.println(byName1);
//      通过getHostAddress对象使他获得对应的地址ipv4地址
        String hostAddress = byName1.getHostAddress();
        System.out.println(hostAddress);
//      获取对应的域名
        String hostName = byName1.getHostName();
        System.out.println(hostName);
    }
}

 运行结果

LAPTOP-D83EFCRR/192.168.0.103
LAPTOP-D83EFCRR/192.168.0.103
www.baidu.com/220.181.38.150
220.181.38.150
www.baidu.com

二.Socket网络编程

数据在两个socket当中通过io流进行传播

 一段服务,一段客户。服务端进行监听,客户端进行信息的发送。数据通道两端的插头。

 双向通道,可读可写

Tcp编程和Udp编程都会使用到socket

 

 案例:

1.使用字节流的形式

要求

思路

 服务端处理多个socket的情况

代码

客户端
SocketTCP01Client 

package com.api.socket_;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class SocketTCP01Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

        System.out.println("客户端Socket返回"+socket.getClass());
//        得到与socket关联的数据通道
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,server".getBytes());
//        将流关闭
        outputStream.close();
        socket.close();
        System.out.println("客户端关闭");
    }

}

服务端

SocketTCP01Server

package com.api.socket_;


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

public class SocketTCP01Server {
    public static void main(String[] args) throws IOException {
//        要求电脑上没有其他程序在监听9999接口
        ServerSocket serverSocket = new ServerSocket(9999);

        System.out.println("服务器在9999端口进行监听");
        //程序阻塞,不再向下执行  如果有客户端socket链接,返回一个socket链接,开始向下执行
        Socket socket = serverSocket.accept();
        System.out.println("客户端 socket = "+socket.getClass());
//      客户端没有发送消息的话,会堵塞在这里
        InputStream inputStream = socket.getInputStream();

        byte[] bytes = new byte[1024];

        int readLine = 0 ;
        while ((readLine = inputStream.read(bytes))!=-1) {
            System.out.println(new String(bytes,0,readLine));//根据读取到的实际长度来读写内容
        }

//        关闭socket
        inputStream.close();
        socket.close();
        serverSocket.close(); //全部进行关闭,serverSocket可以创建很多的socket,有多个客户端来链接的情况
    }
}

 2.依旧是字节流案例

双向交流

 服务端

 SocketTCP02Server

package com.api.socket_;


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

public class SocketTCP02Server {
    public static void main(String[] args) throws IOException {
//        要求电脑上没有其他程序在监听9999接口
        ServerSocket serverSocket = new ServerSocket(9999);

        System.out.println("服务器在9999端口进行监听");
        //程序阻塞,不再向下执行  如果有客户端socket链接,返回一个socket链接,开始向下执行
        Socket socket = serverSocket.accept();
        System.out.println("客户端 socket = "+socket.getClass());
//      客户端没有发送消息的话,会堵塞在这里
        InputStream inputStream = socket.getInputStream();

        byte[] bytes = new byte[1024];

        int readLine = 0 ;
        while ((readLine = inputStream.read(bytes))!=-1) {
            System.out.println(new String(bytes,0,readLine));//根据读取到的实际长度来读写内容
        }

        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,客户端".getBytes());
//        设置结束标记
        socket.shutdownOutput();

//        关闭socket
        outputStream.close();
        inputStream.close();
        socket.close();
        serverSocket.close(); //全部进行关闭,serverSocket可以创建很多的socket,有多个客户端来链接的情况
    }
}

运行结果

 服务器在9999端口进行监听
客户端 socket = class java.net.Socket
hello,server

 客户端

SocketTCP02Client 

package com.api.socket_;

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

public class SocketTCP02Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

        System.out.println("客户端Socket返回"+socket.getClass());
//        得到与socket关联的数据通道
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,server".getBytes());

        InputStream inputStream = socket.getInputStream();

        byte[] bytes = new byte[1024];
        int readLine = 0;
        while ((readLine = inputStream.read(bytes))!=-1){
            System.out.println(new String(bytes,0,readLine));
        }
//      执行之后,会卡在这里,因为不知道什么时候结束。 要设计一个结束的标记
        socket.shutdownInput();
//        将流关闭
        inputStream.close();
        outputStream.close();
        socket.close();
        System.out.println("客户端关闭");
    }
}

客户端Socket返回class java.net.Socket
客户端关闭 

最后记得设置通信结束标志socket.shutdownInput();

3.案例三,使用字符流

 客户端

SocketTCP03Client

package com.api.socket_;

import javax.print.attribute.standard.OutputDeviceAssigned;
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class SocketTCP03Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

        System.out.println("客户端Socket返回"+socket.getClass());
//        得到与socket关联的数据通道
        OutputStream outputStream = socket.getOutputStream();
//        要求使用字符流
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("你好,服务端。。");
        bufferedWriter.newLine();//对方要使用readLine来确定什么时候结束
        bufferedWriter.flush();

        InputStream inputStream = socket.getInputStream();

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        bufferedReader.readLine();
        System.out.println(s);


//        将流关闭 直接关闭字符流,而不是关闭字节流。
        bufferedReader.close();
        bufferedWriter.close();
        socket.close();
        System.out.println("客户端关闭...");
    }
}

客户端Socket返回class java.net.Socket
hello,客户端,字符流
客户端关闭... 

服务端

 SocketTCP02Server

package com.api.socket_;


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

public class SocketTCP03Server {
    public static void main(String[] args) throws IOException {
//        要求电脑上没有其他程序在监听9999接口
        ServerSocket serverSocket = new ServerSocket(9999);

        System.out.println("服务器在9999端口进行监听");
        //程序阻塞,不再向下执行  如果有客户端socket链接,返回一个socket链接,开始向下执行
        Socket socket = serverSocket.accept();
        System.out.println("客户端 socket = "+socket.getClass());
//      客户端没有发送消息的话,会堵塞在这里
        InputStream inputStream = socket.getInputStream();
//      使用了转换流,将字节流转化为了字符流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        String s = bufferedReader.readLine();
        System.out.println(s);

        OutputStream outputStream = socket.getOutputStream();
//        使用字符流来进行返回
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write("hello,客户端,字符流");
//        结束标志
        bufferedWriter.newLine();
//        刷新一下才会输入近数据通道
        bufferedWriter.flush();



//        关闭socket
        bufferedWriter.close();
        bufferedReader.close();
        socket.close();
        serverSocket.close(); //全部进行关闭,serverSocket可以创建很多的socket,有多个客户端来链接的情况

        System.out.println("服务端关闭。。。。");
    }
}

 服务器在9999端口进行监听
客户端 socket = class java.net.Socket
你好,服务端。。
服务端关闭。。。。

简单理一下思路:

首先分为客户端和服务端,服务端使用SocketService.accpet来创建socket。根据链接的客户端的数量创建的socket,之后创建与socket关联的流,通过相关方法,如将数据输入。一般一个端是要有输入和输出两种方法的。还有注意一下如何进行字节和字符流之间的转换,用BufferWriter来转换,之后记得是红newLine方法来表示语句结束,flush方法来刷新流,最后关闭流,有字符流就不用再关闭字节流了,后开的,先关闭。

4.使用字符流传递图片

流程图

客户端

TCPUploadClient类

package com.upload;

import com.utilty.StreamUtils;

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

public class TCPUploadClient {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("127.0.01", 8888);

//        将文件读到文件字节数组当中
        String filePath = "d:\\01.jpg";

        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
//      得到文件对应的字节数组
        byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
//      得到socket对应的输出流
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
        bufferedOutputStream.write(bytes);
        bufferedInputStream.close();
        socket.shutdownOutput();


        InputStream inputStream = socket.getInputStream();
        String string = StreamUtils.streamToString(inputStream);
        System.out.println(string);



        inputStream.close();
        bufferedOutputStream.close();
        socket.close();
    }
}

输出结果

 已经收到了图片

服务端 

TCPUpLoadService类

package com.upload;

import com.utilty.StreamUtils;

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

public class TCPUpLoadService {
    public static void main(String[] args) throws Exception {

        ServerSocket serverSocket = new ServerSocket(8888);
        System.out.println("服务端在本机监听 8888 端口");

        Socket socket = serverSocket.accept();
//      获得socket相关的输入流
        BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
//      将byte写入输出流
        String filePath = "src\\dongman2.jpg";
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath));
        bufferedOutputStream.write(bytes);
        bufferedOutputStream.close();

//        向客户端返回结果通知
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bufferedWriter.write("已经收到了图片");
        bufferedWriter.flush();
        socket.shutdownOutput();

        bufferedWriter.close();
        bufferedInputStream.close();
        socket.close();
        serverSocket.close();
    }
}

输出结果

服务端在本机监听 8888 端口 

使用的工具类

package com.utilty;


import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;

public class StreamUtils {
    public static byte[] streamToByteArray(InputStream is) throws Exception {
        // 创建输出流对象
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        // 字节数组
        byte[] b = new byte[1024];
        int len;
        while ((len = is.read(b)) != -1) {
            // 循环读取
            // 把读取到的数据,写入 bos
            bos.write(b, 0, len);
        }
        byte[] array = bos.toByteArray();
        bos.close();
        return array;
    }

    public static String streamToString(InputStream is) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder builder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            builder.append(line + "\r\n");
        }
        return builder.toString();
    }
}

5.netstat指令

 三。通信协议的理解

1。tcp协议的一个小秘密

客户端也是通过一个端口来和服务端来进行链接的,但是这个端口是根据协议,随机分配的。

2.UDP网络编程(了解)

1.介绍

2.流程

 

 UDPServiceA类

package com.UDP;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class UDPServiceA {
    public static void main(String[] args) throws IOException {
        //准备在9999端口等待接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9999);
//        最大的传送量在64kb
        byte[] bytes = new byte[1024];
//
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
//        将包裹放到socket当中
        System.out.println("接收端A在等待接受数据");
//        如果每有接受到数据就会阻塞
        datagramSocket.receive(datagramPacket);

        int length = datagramPacket.getLength();//接受字节长度
        byte[] data = datagramPacket.getData(); //接收数据
        String string = new String(data, 0, length);//将数据解析成字符串
        System.out.println(string);

//        对要发送的数据进行封装
        byte[] bytes1 = "好的,明天一定准时到".getBytes();
        System.out.println("发送 :好的,明天一定准时到");
        DatagramPacket datagramPacket1 = new DatagramPacket(bytes1, bytes1.length, InetAddress.getLocalHost(), 9998);
//        进行发送
        datagramSocket.send(datagramPacket1);

        datagramSocket.close();

    }

}

 接收端A在等待接受数据
明天要不要吃火锅
发送 :好的,明天一定准时到

UDPSendsB类

package com.UDP;

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

public class UDPSendsB {
    public static void main(String[] args) throws IOException {
//            发送消息给A端
        //在9998端口准备接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9998);
//        对要发送的数据进行封装
        byte[] bytes = "明天要不要吃火锅".getBytes();
        System.out.println("发送: 明天要不要吃火锅");
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 9999);
//        进行发送
        datagramSocket.send(datagramPacket);

        byte[] bytes1 = new byte[1024];
//
        DatagramPacket datagramPacket1 = new DatagramPacket(bytes1, bytes.length);
//        将包裹放到socket当中
        System.out.println("接收端A在等待接受数据");
//        如果每有接受到数据就会阻塞
        datagramSocket.receive(datagramPacket1);

        int length = datagramPacket1.getLength();//接受字节长度
        byte[] data = datagramPacket1.getData(); //接收数据
        String string = new String(data, 0, length);//将数据解析成字符串
        System.out.println(string);

        datagramSocket.close();

    }
}

发送: 明天要不要吃火锅
接收端A在等待接受数据
好的,明天一定准 

因为是以包的形式来发送的时候,所以会感觉UDP编程相对简单。 

四。课后的作业

1。作业一

 服务端
HouseWork01Server

package com.homework;

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

public class HouseWork01Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        Socket socket = serverSocket.accept();

        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        String name = "";

        if ("name".equals(s)){
            System.out.println("我的名字是tom");
        }else if("hobby".equals(s)){
            System.out.println("我的爱好是学习java");
        }else {
            System.out.println("你说的啥子!");
        }
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write(name);
        bufferedWriter.newLine();
        bufferedWriter.flush();

        bufferedWriter.close();
        bufferedReader.close();
        socket.close();
        serverSocket.close();

        System.out.println("服务端退出。。。。");
    }
}

我的名字是tom
服务端退出。。。。 

客户端

HouseWork01Client

package com.homework;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class HouseWork01Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 9999);

        OutputStream outputStream = socket.getOutputStream();
//        创建字节流  字节流似乎更方便这种功能的实现
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        System.out.println("请输入你的问题");
        Scanner scanner = new Scanner(System.in);
        String next = scanner.next();

        bufferedWriter.write(next);
        bufferedWriter.newLine();
        bufferedWriter.flush();

        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//        直接读取数据,以字符串的形式返回
        String s = bufferedReader.readLine();
        System.out.println(s);

        bufferedReader.close();
        bufferedWriter.close();
        socket.close();
        System.out.println("客户端退出。。。。");
    }
}

请输入你的问题
name

客户端退出。。。。

可以思考一下如何一直问,并且可以一直得到答案,除非退出。 

2.课后作业二

要求

接收端
HomeWorkReceiverA

package com.homework;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class HomeWorkReceiverA {
    public static void main(String[] args) throws IOException {
        //准备在9999端口等待接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9999);
//        最大的传送量在64kb
        byte[] bytes = new byte[1024];
//
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
//        将包裹放到socket当中
        datagramSocket.receive(datagramPacket);

        int length = datagramPacket.getLength();//接受字节长度
        byte[] data = datagramPacket.getData(); //接收数据
        String string = new String(data, 0, length);//将数据解析成字符串
//        判断接受到的信息是什么\
        String answer = "";
        if ("四大名著是那些".equals(string)){
            System.out.println("四大名著有红楼梦,有三国演义,西游记。");
        }else {
            answer = "what";
        }
//        对要发送的数据进行封装
        byte[] bytes1 = answer.getBytes();
        DatagramPacket datagramPacket1 = new DatagramPacket(bytes1, bytes1.length, InetAddress.getLocalHost(), 9998);
//        进行发送
        datagramSocket.send(datagramPacket1);

        datagramSocket.close();

        System.out.println("接收端A结束");
    }
}

四大名著有红楼梦,有三国演义,西游记。
接收端A结束

发送端

HomeWorkSendB

package com.homework;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class HomeWorkSendB {
    public static void main(String[] args) throws IOException {
//            发送消息给A端
        //在9998端口准备接收数据
        DatagramSocket datagramSocket = new DatagramSocket(9998);
//        对要发送的数据进行封装
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的问题");
        String next = scanner.next();
        byte[] bytes = next.getBytes();

        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getLocalHost(), 9999);
//        进行发送
        datagramSocket.send(datagramPacket);

        byte[] bytes1 = new byte[1024];
//
        DatagramPacket datagramPacket1 = new DatagramPacket(bytes1, bytes.length);
//        将包裹放到socket当中
        System.out.println("接收端A在等待接受数据");
//        如果每有接受到数据就会阻塞
        datagramSocket.receive(datagramPacket1);

        int length = datagramPacket1.getLength();//接受字节长度
        byte[] data = datagramPacket1.getData(); //接收数据
        String string = new String(data, 0, length);//将数据解析成字符串
        System.out.println(string);

        datagramSocket.close();

    }
}

请输入你的问题
四大名著是那些
接收端A在等待接受数据

 3.课后作业三

要求

思路

 客户端

Homework03Client类

public class Homework03Client {
    public static void main(String[] args) throws Exception {
 
 
        //1. 接收用户输入,指定下载文件名
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入下载文件名");
        String downloadFileName = scanner.next();
 
        //2. 客户端连接服务端,准备发送
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        //3. 获取和Socket关联的输出流
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(downloadFileName.getBytes());
        //设置写入结束的标志
        socket.shutdownOutput();
 
        //4. 读取服务端返回的文件(字节数据)
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        //5. 得到一个输出流,准备将 bytes 写入到磁盘文件
        String filePath = "e:\\" + downloadFileName + ".mp3";
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
        bos.write(bytes);
 
        //6. 关闭相关的资源
        bos.close();
        bis.close();
        outputStream.close();
        socket.close();
 
        System.out.println("客户端下载完毕..");
 
 
    }
}

服务端

Homework03Server类

public class Homework03Server {
    public static void main(String[] args) throws Exception {
 
        //1 监听 9999端口
        ServerSocket serverSocket = new ServerSocket(9999);
        //2.等待客户端连接
        System.out.println("服务端,在9999端口监听,等待下载文件");
        Socket socket = serverSocket.accept();
        //  使用了while读取文件名,时考虑将来客户端发送的数据较大的情况
        InputStream inputStream = socket.getInputStream();
        byte[] b = new byte[1024];
        int len = 0;
        String downLoadFileName = "";
        while ((len = inputStream.read(b)) != -1) {
            downLoadFileName += new String(b, 0 , len);
        }
        System.out.println("客户端希望下载文件名=" + downLoadFileName);

        //如果客户下载的是 高山流水 我们就返回该文件,否则一律返回 无名.mp3
 
        String resFileName = "";
        if("高山流水".equals(downLoadFileName)) {
            resFileName = "src\\高山流水.mp3";
        } else {
            resFileName = "src\\无名.mp3";
        }
 
        //4. 创建一个输入流,读取文件
        BufferedInputStream bis =
                new BufferedInputStream(new FileInputStream(resFileName));
 
        //5. 使用工具类StreamUtils
 
        byte[] bytes = StreamUtils.streamToByteArray(bis);
        //6. 得到Socket关联的输出流
        BufferedOutputStream bos =
                new BufferedOutputStream(socket.getOutputStream());
        //7. 写入到数据通道,返回给客户端
        bos.write(bytes);
        socket.shutdownOutput();
 
        //8 关闭相关的资源
        bis.close();
        inputStream.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端退出...");
 
    }
}

后面的QQ聊天室的项目

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到