深大互联网编程实验1-熟悉互联网编程开发环境

由于这是课程实验大作业记录,所以决定不拘于文章的编排格式,虽然看起来可能有点费劲,但是也算是清楚明了呈现,图片是从word文档转过来的,所以像素会被压缩模糊了一些,但也是可以接受的,希望对有需要的朋友能有所帮助。

----------------------------------------------------------------------------------------------------------------------------
 

一、实验目的与内容:

目的:掌握面向java的互联网编程开发环境的搭建。学习、掌握java网络程序编写基本步骤,例如,基于MyEclipse或者IntelliJ IDEA平台编写简单的基于 TCP 的 单线程文件收发程序,掌握编译、运行等基本步骤和操作。

内容要求:

  1. 搭建开发环境(基本要求,50分):

(在自己电脑上)下载安装和配置Java开发环境(如Eclipse或IntelliJ IDEA等),并熟悉该开发环境中的常用操作。

请在报告中给出搭建环境成功的截图和简要文字说明,简述自己所了解掌握的常用操作。

  1. 尝试编写一个基于 TCP 的单线程文件收发程序(CS架构)(50分):

可试着根据java编程课所学到的java socket编程技术,尝试编写一个基于 TCP 的单线 程文件收发程序,需满足:

服务端程序预先定义好需要发送的文件并等待客户端的连接。

客户端连接成功后,服务端将文件发送给客户端,客户端将文件保存到本地。

需要在同一个 TCP 连接内发送多个文件,不限制文件的类型和大小(操作系统支持的前提 下)。

注意: 实验报告中需要有实验结果的截屏图像。

二、实验过程和代码与结果

1.开发环境的搭建实验过程及结果

由于之前已经安装过IDEA,又为了记录一下IntelliJ IDEA的安装与环境搭建,所以选择先卸载然后重新安装并配置IDEA;以下为详细过程:

1)下载;

深大互联网编程实验1-熟悉互联网编程开发环境_第1张图片

2)安装

深大互联网编程实验1-熟悉互联网编程开发环境_第2张图片

3)安装成功后目录结构:

深大互联网编程实验1-熟悉互联网编程开发环境_第3张图片

bin:容器,执行文件和启动参数等

help:快捷键文档和其他帮助文档

jbr:全称为 JetBrains Runtime, 是IDEA自带的Java运行环境

lib: idea 依赖的类库

license:各个插件许可

plugins:插件

redist:一些杂项

4)启动IDEA并登陆学生账号;

深大互联网编程实验1-熟悉互联网编程开发环境_第4张图片

5)创建一个工程同时随意命名为project,同时依次打开File->Project Structure设置SDK;

深大互联网编程实验1-熟悉互联网编程开发环境_第5张图片

6)在setting里面设置字的大小和行高

深大互联网编程实验1-熟悉互联网编程开发环境_第6张图片

7)调试编程输出“Hello World!”;

深大互联网编程实验1-熟悉互联网编程开发环境_第7张图片

8)创建模块(Module)

IDEA 是无法在同一个窗口管理n个项目。 IDEA提供的解决方案是打开多个项目实例,即打开多个项目窗口。即:一个Project打开一个Window窗口。

在IDEA中Project是最顶级的级别,次级别是 Module。一个Project可以有多个Module。

深大互联网编程实验1-熟悉互联网编程开发环境_第8张图片

深大互联网编程实验1-熟悉互联网编程开发环境_第9张图片

之后,我们可以在Module的src里写代码,此时Project工程下的src就没什么用了,可

深大互联网编程实验1-熟悉互联网编程开发环境_第10张图片

9)通过插件(plugins)更换主题

深大互联网编程实验1-熟悉互联网编程开发环境_第11张图片

10)设置鼠标滚轮修改字体大小

深大互联网编程实验1-熟悉互联网编程开发环境_第12张图片

11)设置自动导包功能

深大互联网编程实验1-熟悉互联网编程开发环境_第13张图片

12)修改类头的文档注释信息

深大互联网编程实验1-熟悉互联网编程开发环境_第14张图片

13)设置项目文件编码

深大互联网编程实验1-熟悉互联网编程开发环境_第15张图片

14) 设置当前源文件的编码

对单独文件的编码修改还可以点击右下角的编码设置区。如果代码内容中包含中文,则会弹出如上的操作选择。 其中:

①Reload 表示使用新编码重新加载,新编码不会保存到文件中,重新打开此文件,旧编码是什么依旧还是什么。

②Convert 表示使用新编码进行转换,新编码会保存到文件中,重新打开此文件,新编码是什么则是什么。

③含有中文的代码文件, Convert 之后可能会使中文变成乱码,所以在转换成请做好备份,不然可能出现转换过程变成乱码,无法还原。

深大互联网编程实验1-熟悉互联网编程开发环境_第16张图片

深大互联网编程实验1-熟悉互联网编程开发环境_第17张图片

15)设置快捷键(Keymap)

深大互联网编程实验1-熟悉互联网编程开发环境_第18张图片

16)在Debugger里transport把socket改成shared memory以节省内存;

深大互联网编程实验1-熟悉互联网编程开发环境_第19张图片

17)debug操作

首先点好断点,然后右键-debug出现下图:第一行(前4个箭头)从左到右是

step over下一步(不进入方法内)(F8

step into下一步(进入方法内)(F7

force step into 下一步(进入方法内)(alt+shift+F7)

*step into会进入你自己写的方法。force step into能够进入所有的方法,比如jdk的方法。

step out 跳出(shfit+F8

红色正方形是stop(ctrl+F2)

小结:由第7)点和第8)点可以看出已经可以成功调试并运行程序,说明环境已经搭建成功。

见图:

深大互联网编程实验1-熟悉互联网编程开发环境_第20张图片

深大互联网编程实验1-熟悉互联网编程开发环境_第21张图片

2. 给出满足内容要求2的程序源码及运行结果,简述思路或实验过程。

1)同一个 TCP 连接内发送多个文件的本地目录

深大互联网编程实验1-熟悉互联网编程开发环境_第22张图片

2)传输成功后的目标存储地址

深大互联网编程实验1-熟悉互联网编程开发环境_第23张图片

3)我的基于 TCP 的单线程文件收发程序的编写思路

一次传输一个文件比较简单,但是在一次传输多个文件时会遇到这样的问题,怎样在接收文件时确定文件之间的边界呢?为了在接收端正确的拆分文件,决定在传输文件时须要传输每一个文件的大小。于是采用了这样一种策略:首先发送每一个文件的名称和大小。然后传输每一个文件的内容。部分代码如下(同一个包下建了三个class,分别是服务端(Service)、客户端(Client)静态函数接口端(StreamUtils)):

① Service端调用函数发送多个文件

深大互联网编程实验1-熟悉互联网编程开发环境_第24张图片

StreamUtils端写入多个文件

深大互联网编程实验1-熟悉互联网编程开发环境_第25张图片

③读取文件核心代码(代码有充分注释)

深大互联网编程实验1-熟悉互联网编程开发环境_第26张图片

详细代码见 实验一源码.zip

4)实验过程及结果

①传输文件前:

深大互联网编程实验1-熟悉互联网编程开发环境_第27张图片

②运行程序传输文件后:

深大互联网编程实验1-熟悉互联网编程开发环境_第28张图片

深大互联网编程实验1-熟悉互联网编程开发环境_第29张图片

深大互联网编程实验1-熟悉互联网编程开发环境_第30张图片

实验完毕。

三、实验总结

(此处写你的过程,比如遇到的错误,以及解决方法,你的所想、所得)

实验内容一:我下载重装并重新配置Java开发环境(IntelliJ IDEA),并熟悉该开发环境中的常用操作比如:打开File->Project Structure设置SDK、在setting里面设置字的大小和行高、创建模块(Module)、通过插件(plugins)更换主题、设置鼠标滚轮修改字体大小、设置自动导包功能、修改类头的文档注释信息、设置项目文件编码、设置当前源文件的编码、设置快捷键(Keymap)、在Debugger里transport把socket改成shared memory以节省内存、debug操作等等,总体难度较小,花时间和心思查阅一下资料同时上手操作熟悉便就做完。

不过在其中遇到个问题:idea中java项目增加module后,增加的目录(src)无法增加包(Package)。解决方法:需要将新增src目录变为Sources Root即可。

实验内容二:一次传输一个文件比较简单,但是在一次传输多个文件时会遇到这样的问题,怎样在接收文件时确定文件之间的边界呢?为了在接收端正确的拆分文件,决定在传输文件时须要传输每一个文件的大小。于是采用了这样一种策略:首先发送每一个文件的名称和大小,然后传输每一个文件的内容。最后在客户端接受并保留到指定地址即可。

感想:我是挺想学Java编程的,上学期没有选修上也没有加位Java基础课,虽然这门互联网编程课前提要有Java基础,但是这并不妨碍我学习这门课,一是我较早学了Java基础,之前掌握了C++和C上手Java就很快;二是也学习了舍友的Java课的大作业实验,心里对Java有底。这个实验帮我熟悉并记录了Java开发环境配置与常用操作,以及实操了基于 TCP 的单线程文件收发程序,收获充足,自己也有不足的地方,比如在一次性发送多个文件的程序设计中,除了上述方式外并没有拓展想出新传输方式,希望迟点能在答案中启发新的思路。未来希望自己在这门课的学习中有所成长,提升自己的Java互联网编程能力,希望自己不要羡于形形色色的方法论和技巧,脚踏实地,知行合一,深入思考,一步一个脚印地学,宁拙勿巧,做一个诚心想学的学徒。

(请在报告中给出搭建环境成功的截图和简要文字说明,简述自己所了解掌握的常用操作。)

指导教师批阅意见:

成绩评定:

                                    指导教师签字: 

                                                    年    月    日

备注:

注:1、报告内的项目或内容设置,可根据实际情况加以调整和补充。

    2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。

补充:实验内容二源码(2022.3.17修复了一个bug后编辑)

package socket2;

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

/**
 * @author 吕同学
 * @create 2022-03-13 22:24
 */
public class Service {
    //发现必须要处理异常,不处理就会报错,可以用 throws,也可以用 try...catch
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(8888);//创建socket对象并监听8888端口
        System.out.println("服务器成功启动,在8888端口监听,等待连接\n");

        //等待客户端连接
        Socket socket = serverSocket.accept();
        System.out.println("socket连接成功!");

        //创建读取磁盘文件的输入流
        File srcFile = new File("D:\\javaHomeworkFiles");
        File[] files = srcFile.listFiles();
        //服务端调用函数发送文件
        StreamUtils.sendFiles(socket,files);


        //=====接收从服务端回复的消息=====
        InputStream inputStream = socket.getInputStream();
        //使用StreamUtils 的方法,直接将 inputStream 读取到的内容 转成字符串
        String s = StreamUtils.streamToString(inputStream);
        System.out.println(s);

        //关闭流和socket
        socket.close();
        serverSocket.close();//关闭
    }
}
package socket2;

import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.Socket;

/**
 * @author 吕同学
 * @create 2022-03-13 11:19
 */
public class Client {
    public static void main(String[] args) throws Exception {
        //客户端连接服务端 8888,得到Socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
        System.out.println("客户端成功连接服务端 8888,得到Socket对象");

        //客户端从服务端接受文件
        StreamUtils.receiveFiles(socket);

        // 通过socket获取到输出流(字符)
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        writer.write("客户端成功收到文件并保存到了指定地址");
        writer.flush();//把内容刷新到数据通道
        socket.shutdownOutput();//设置写入结束标记

        //关闭其他资源
        writer.close();
        socket.close();
    }
}
package socket2;

/**
 * @author 吕同学
 * @create 2022-03-13 11:12
 */

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

/**
 * 功能:将输入流转换成byte[]
 */
public class StreamUtils {
    public static byte[] streamToByteArray(InputStream is) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();//创建输出流对象
        byte[] b = new byte[1024];
        int len=is.read(b);
//        while ((len = is.read(b)) != -1) {
//            bos.write(b, 0, len);
//        }
        bos.write(b, 0, len);
        byte[] array = bos.toByteArray();
        bos.close();
        return array;
    }

    /**
     * 功能:将InputStream转换成String
     */
    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) { //当读取到 null时,就表示结束
            builder.append(line + "\r\n");
        }
        return builder.toString();
    }

    /**
     * 功能:发送多个文件
     */
    public static void sendFiles(Socket socket, File[] files) throws Exception {
        long totalSize = 0;
        int len;
//        byte buf[] = new byte[9999];

        DataOutputStream dout = new DataOutputStream(socket.getOutputStream());
        //将文件数量大小写入数据通道
        dout.writeInt(files.length);

        for (int i = 0; i < files.length; i++) {
            //写入文件名
            dout.writeUTF(files[i].getName());
            dout.flush();
            //写入单个文件长度,用以正确拆分不同文件,注意写入的格式是不一样的
            dout.writeLong(files[i].length());
            dout.flush();
            totalSize += files[i].length();
        }
        dout.writeLong(totalSize);

        for (int i = 0; i < files.length; i++) {
            BufferedInputStream din = new BufferedInputStream(new FileInputStream(files[i]));
//            while ((len = din.read(buf)) != -1) {
//                dout.write(buf, 0, len);
//            }
            byte[] buf=streamToByteArray(din);
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
            //将文件对应内容的字节数组学写入
            bos.write(buf);
            bos.flush();
            //bos.close();
        }
        System.out.println("文件传输完毕");

        //socket.shutdownOutput();
        return;
    }

    /**
     * 功能:接收多个文件
     */
    public static void receiveFiles(Socket socket) throws Exception {
        long totalSize = 0;

        DataInputStream din = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
        //fileNum是传输文件的数量
        int fileNum = din.readInt();
        String[] fileinfos = new String[fileNum];

        Long[] nums=new Long[fileNum];
        for (int i = 0; i < fileNum; i++) {
            fileinfos[i] = din.readUTF();
            System.out.println(fileinfos[i]);
            //这个判断仅仅是为了读取fileinfos[i]的长度,但不作任何处理
            if (fileinfos[i].length() == din.readLong())
                continue;
        }
        //仅仅是为了读取fileinfos的总长度,不作任何处理
        totalSize = din.readLong();

        for(int i=0;i

我是吕同学,祝自己也您变强了~

你可能感兴趣的:(java,intellij-idea,intellij,idea,学习,经验分享)