23年网络编程期末冲刺


大概总结一下老师说的期末要考的内容吧,代码部分都是举个最简单的例子,理解了应该就行。

主要分了两块,上半是前面相当于回顾的知识,后半才真算是网络编程的知识。

上半

TCP/UDP发送与接收

这里应该是只要会写写代码就行吧

TCP发送端
import java.io.*;
import java.net.*;

public static void main(String[] args)throws IOException {
    String str = "信息";
    Socket s = new Socket("127.0.0.1",1234);
    OutputStream out = s.getOutputStream();
    out.write(str.getBytes());
}
TCP接收端
import java.io.*;
import java.net.*;

public static void main(String[] args)throws IOException {
	ServerSocket ss = new ServerSocket(1234);
    Socket s = ss.accept();
	InputStream in = s.getInputStream();
    byte[] buf = new byte[1024];
    int num = in.read(buf);
    String str = new String(buf,0,num);
    System.out.println(str);
    s.close();
    ss.close();
}

UDP发送端
import java.io.*;
import java.net.*;

public static void main(String[] args)throws IOException {
    String str = "信息";
    DatagramSocket ds = new DatagramSocket();
    byte[] buf = str.getBytes();
    DatagramPacket dp = new DatagramPacket(buf,0,buf.length,InetAddress.getByName("127.0.0.1"),1234);
    ds.send(dp);
    ds.close();
}
UDP接收端
import java.io.*;
import java.net.*;

public static void main(String[] args)throws IOException {
	DatagramSocket ds = new DatagramSocket(1234);
	byte[] buf = new byte[1024];
	DatagramPacket dp = new DatagramPacket(buf,buf.length);
	ds.receive(dp);
	String str = new String(dp.getData(),0,dp.getLength());
	System.out.println(str);
}

多线程

下面是一个最简单的例子,通过实现Runnable接口里的run方法实现的多线程

MyRunnable里写每个线程的代码,这里举的例子是输出0-4

class MyRunnable implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i);
        }
    }
}

public class ttt {//ttt是类名

    public static void main(String args[]) {
        Thread thread1 = new Thread(new MyRunnable());
        Thread thread2 = new Thread(new MyRunnable());

        thread1.start();
        thread2.start();
    }
}

线程池

一个简单的线程池

MyRunnable里写每个线程的代码,这里举的例子是输出自己的ID

import java.util.concurrent.*;

class MyRunnable implements Runnable {
    private final int taskId;
    public MyRunnable(int taskId) {
        this.taskId = taskId;
    }
    public void run() {
        System.out.println(taskId);
    }
}

public class ttt {
    public static void main(String[] args) {
        // 创建一个固定大小的线程池,其中包含两个线程
        ExecutorService executor = Executors.newFixedThreadPool(2);
        // 提交多个任务给线程池执行
        for (int i = 0; i < 5; i++) {
            Runnable task = new MyRunnable(i);
            executor.submit(task);
        }
        // 关闭线程池
        executor.shutdown();
    }
}

HTTP

不太确定老师考啥,可以看ppt先了解一下(自己查的话全看完太多了,我感觉老师应该只考ppt上的)然后老师说的重点是http的定义、特点和提交方式(不确定当时有没有听错,但是我记得就是这些)

定义

老师说是定义,不过我觉得应该是运行方式和原理,反正大概就是这些了解下就行吧:

HTTP简单介绍

HTTP是HyperText Transfer Protocol(超文本传输协议)的简写,它是TCP/IP协议的一个应用层协议,用于定义浏览器与WEB服务器之间交换数据的过程及数据本身的格式。默认端口号是80

请求报文和响应报文

一个完整的HTTP请求包括如下内容:一个请求行、若干消息头、以及请求正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用空行隔开

一个完整的HTTP响应包括如下内容:一个状态行、若干消息头、以及响应正文,其中的一些消息头和正文都是可选的,消息头和正文内容之间要用空行隔开。

特点

ppt上没写这点,但是搜到的内容和运行原理那节写的差不多,网上搜到的是简单快速、灵活、无连接、无状态

HTTP运行原理

基于HTTP协议的客户/服务器模式的信息交换过程,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接。

浏览器与WEB服务器的连接过程是短暂的每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接。

浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应。

无状态

提交方式

ppt上和搜到的都是请求方式。。应该是老师说错了或者我记错了

请求行请求方式:GET、POST、HEAD、OPTIONS、DELETE、TRACE、PUT

登录和上传文件一般都选用post,比较安全。

下半

从这里开始才是真正的网络编程部分,前面的都是打基础的(其实http也算下半,但是感觉下半部分太多了,它也只用了解一下,所以就分到上半了),我记得老师好像还讲了IO啥的,但是划重点的时候好像没说,就不管了吧

Servlet

不知道到时候会不会让写这个代码,感觉应该不会,毕竟挺复杂的,不过还是总结下

介绍和书写
介绍

Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。

web.xml部分
<web-app>
	<servlet>
	    <servlet-name>Login</servlet-name>
		<!--这里写你起的名字,要和下面mapping那个对应-->
		<servlet-class>servlet.Login</servlet-class>
		<!--这里是你写java代码的位置,和其它的不太一样,是用.代表下一级,从src开始计算,比如这个就是src下的serclet文件夹里的Login.java文件(.java要省去)-->
	</servlet>
	<servlet-mapping>
		<servlet-name>Login</servlet-name>
		<!--这个和上面的名字对应-->
		<url-pattern>/login</url-pattern>
		<!--这里写你想在哪个位置(就是网址)调用这你写的代码-->
	</servlet-mapping>
</web-app>

看名字也比较好懂其实,mapping是映射的意思,就是把那个位置的代码映射到这个网址上调用

Java部分

主要是有四个方法

  • 一个是init() 初始化,只在创建的时候调用一次,没有参数
  • doGet() 在收到get请求(比如说访问这个页面)时做的动作。一共俩参数HttpServletRequest和HttpServletResponse (还是考英语,一个是请求,一个是响应)request用来处理人家传过来的信息,就相当于是读信息;response就是给人家传信息,相当于发信息
  • doPost() 在收到post请求(最常见的就表单提交到这里了)做的动作,参数和doGet()的一样。
  • destroy() 是销毁这个线程,就最后调用一次,到后面生命周期的时候再说吧。

从菜鸟教程上粘了一段例子,比较简单,也挺全,不过没写doPost,我加了点,大概是这样

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class HelloWorld extends HttpServlet {
 
  private String message;

  public void init() throws ServletException {
      // 执行必需的初始化(我们写的代码有时候可以不做初始化)
      message = "Hello World";
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      // 设置响应内容类型
      response.setContentType("text/html");

      // 实际的逻辑是在这里
      PrintWriter out = response.getWriter();//这里是获得了response的输出,反正就是可以用这个out往页面写东西了
      out.println("<h1>" + message + "</h1>");//这里可以写html代码的,反正总之就是个字符串,合成之后当html看就行了
  }
    
  public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	String user = request.getParameter("user");
	String password = request.getParameter("pwd");//这里是获得了传进来的用户名和密码
    if (user.equals("admin") && password.equals("123456")) {//判断一下
		PrintWriter out = response.getWriter();
      	out.println("<h1>登录成功!</h1>");
    } else {
        PrintWriter out = response.getWriter();
      	out.println("<h1>账号密码不匹配!</h1>");
    }//根据判断在当前页面
  }
    
  public void destroy() {
      // 什么也不做
  }
}
页面部分

就是html或者jsp代码,就不举例子了

生命周期

其实上面的Java部分提到了,就是那4个方法,这里详细点说说。

Servlet是一个供其他Java程序(Servlet引擎)调用的Java类,它不能独立运行,它的运行完全由Servlet引擎来控制和调度

针对客户端的多次Servlet请求,通常情况下,服务器只会创建一个Servlet实例对象,也就是说Servlet实例对象一旦创建,它就会驻留在内存中,为后续的其它请求服务,直至web容器退出,servlet实例对象才会销毁。默认情况Servlet是单例的

在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doPost或者doGet方法。

线程安全
产生原因

当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

解决办法
  • 使用Java同步机制对多线程同步:运行效率低
  • 使用SingleThreadModel接口
  • 合理决定在Servlet中定义的变量的作用域
其它

可能不考,但是ppt里划了,而且确实挺常用的,就记一下。

跳转(客户端行为)response.sendRedirect(“index.jsp”);

转发(服务器行为)request.getRequestDispatcher(“index.jsp”).forward(request, response);

el表达式

这个还挺多。。没找到PPT,只能现搜了,可以看这里或者这里,比较详细,我稍微挑点我觉得的重点过来吧

先说说使用的前提吧,el表达式是在jsp文件里写的,可以和html代码掺着写,就挺像个变量一样,比如你定义个name是”ZY“,那你写<h 1>${name}</h 1>最后在页面显示的就是h1样式的ZY,去年学的js里其实也有这种写法的,下面讲讲怎么存数据和使用。

写法
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>EL表达式</title>
</head>
<body>
<%
    pageContext.setAttribute("username","mby");
    request.setAttribute("username","ff");
    session.setAttribute("username","gy");
    application.setAttribute("username","pp");
%>
<pre>
        获取作用域中username: ${username}。<br>
        <%-- 默认从小到大的范围中找,找到的第一个返回 --%>
        不在作用域中的: ${password}。
        获取request作用域中的username: ${requestScope.username}。
        获取session作用域中的username: ${sessionScope.username}。
        获取application作用域中的username: ${applicationScope.username}。
  </pre>
</body>
</html>

在这里插入图片描述运行出来大概长这样

<% %>里面的部分是Java代码(jsp里就是这么写java代码的),就是在这4个域里都加了个叫username的变量,分别它们赋值不一样的名字。下面${username}显示的是附给的值,这里显示的是pageContext的username,这是因为它们优先级不一样

优先级

在遇到变量的时候,他会从小到大寻找,找到就显示,如果都没找到就啥也不显示,寻找的顺序是:pageContext->request->session->application(这也是之后要说到的jsp9个内置对象的其中4个)

如果想显示特定域里的变量,就按后面那三个书写,如${requestScope.username},在前面限定一下就行了

EL的隐式对象

老师好像没说这个,但是大概看一下吧还是,但是注意别和jsp的记混了

隐含对象描述
pageScopepage作用域
requestScoperequest作用域
sessionScopesession作用域
applicationScopeapplication作用域
paramRequest对象的参数,字符串
paramValuesRequest对象的参数,字符串集合
headerHTTP信息头,字符串
headerValuesHTTP信息头,字符串集合
initParam上下文初始化参数
cookieCookie值
pageContext当前页面的pageContext

el表达式会这么些感觉差不多了就,我估计就出个小题,问会显示谁的名字,优先级哪里懂了就行。

JSP9大隐式对象

大概记住就行了感觉

编号对象所属作用域作用域描述
1requestrequest在当前请求中有效
2responsepage在当前页面有效
3outpage在当前页面有效
4sessionsession在当前会话中有效
5applicationapplication在所有应用程序中有效
6configpage在当前页面有效
7pageContextpage在当前页面有效
8pagepage在当前页面有效
9Exceptionpage在当前页面有效

过滤器(Filter)

我感觉其实这个也不会让写代码,主要可能考考定义吧,但是既然老师说了,就也都写一下。

概念
简介

Filter为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

如何实现拦截

Filter接口中有一个doFilter方法,当开发人员编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

调用目标资源之前,让一段代码执行

是否调用目标资源(即是否让用户访问web资源)。web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

调用目标资源之后,让一段代码执行

Filter的生命周期

和我们编写的Servlet程序一样,Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(注:filter对象只会创建一次,init方法也只会执行一次。)在Web容器卸载 Filter 对象之前调用destroy()。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源。

实现
web.xml部分
<web-app>
	<filter>
        <filter-name>AuthorityFilter</filter-name>
        <filter-class>servlet.AuthorityFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>AuthorityFilter</filter-name>
        <url-pattern>/Backstage.jsp</url-pattern>
    </filter-mapping>
</web-app>	

这么写应该就行了,和servlet几乎一模一样,好记,不过其实还有好多别的参数,但是太多了,有兴趣去看ppt吧

Java部分
package servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class AuthorityFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);//初始化
    }

    public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
        String name = req.getParameter("name");
        if("admin".equals(name)){
            // 名字合规,把请求传回过滤链
            chain.doFilter(req, resp);
        } else{
            //设置返回内容类型
            resp.setContentType("text/html");

            //在页面输出响应信息
            PrintWriter out = resp.getWriter();
            out.print("<b>name不正确,请求被拦截,不能访问web资源</b>");
        }

    }

    public void destroy() {
        Filter.super.destroy();//销毁
    }
}

和之前的doPost也很像,就是判断通过了要放行,需要传回过滤链chain.doFilter(req, resp);,就相当于交给之后的过滤器(如果有)继续判断。

JDBC(老师说一定考15-20分的大题)

不知道老师要求到什么程度。。就写个最基础的吧,不写userDao啥的了,也不是不能用,而且毕竟是手写代码,写好几个文件也不是很现实

先看一下我的数据库,里面的user表长这样

下面先介绍通用的部分,由于查询它和(删除、修改、插入)这仨不一样,所以后半部分分两种情况,在后面讲

可运行的通用部分
import java.sql.*;

public class Main {
    public static void main(String[] args) {
        String URL = "jdbc:mysql://127.0.0.1:3306/userdata";
        //前面一般不用变的,就最后一个是数据库名会换
        String USER = "root";//数据库账号
        String PASSWORD = "123456";//数据库密码
        try {
            Class.forName("com.mysql.jdbc.Driver");//添加驱动根据自己的版本找,手写应该不用写。。
            Connection conn = DriverManager.getConnection(URL,USER,PASSWORD);
            //
            //在这里根据增删改查不同写不一样的代码
			//
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
手写最简版的通用部分

我感觉啊,像什么引包啊什么的都没啥用,都手写代码了,还引包干啥。。把主要的写上得了,考试的时候这样写就行,或者变量也别定义了,直接写那个getConnection括号里也行,那更短了

String URL = "jdbc:mysql://127.0.0.1:3306/userdata";//前面一般不用变的,最后一个是数据库名会换
String USER = "root";//数据库账号
String PASSWORD = "123456";//数据库密码

Connection conn = DriverManager.getConnection(URL,USER,PASSWORD);
//建立与数据库的连接,变量名自己起,后面会用

//剩下的看查询和修改需要添加的部分
查询
String sql = "select * from user";
//查询的sql 这个根据题目要求来,考试的时候数据库都考完了,不会不会吧
Statement statement = conn.createStatement();
//建立执行对象,conn是前面连接的变量名
ResultSet resultSet = statement.executeQuery(sql);
//执行就行了,因为是查询,所以要找一个结果集来存储查到的结果
while (resultSet.next()){//因为结果很多,而且不知道多少个,所以要用while来判断
	String username = resultSet.getString("username");
	String password = resultSet.getString("password");
	int is_admin = resultSet.getInt("is_admin");
    //这三行根据题上的表的数据类型来,char就用String,int就用int,不过其实好像都用String也不是不行,引号里是列名
	System.out.println(username+" "+password+" "+is_admin);
    //最后输出一下或者判断啥的,如果要判断记得把数据都换成数组(ArrayList当然更好)存起来,后面查完了再判断,这里为了简单就直接输出了
}
删除、插入、更新

删除,插入,更新这仨都差不多,就sql语句换一下其它一点不用变,就以插入为例了

String sql = "insert into user values('mxs','hh',1)";//还是sql语句
Statement statement = conn.createStatement();//还是建立执行对象
int rows = statement.executeUpdate(sql1);//这个是返回的是受影响的行数,只要不是0就说明更新成功了
if (rows != 0) {
	System.out.println("成功!");
} else {
	System.out.println("失败");
}

大概就这样了,好像也没有很多,拆开之后还算好记吧

最后

老师说的重点应该是都总结了,但是还有些没写,比如说IO也学了,但是老师就没说,还有什么session啊cookie啊还有和过滤器一块儿的监听器,也都没说要考,希望是真的不考,而不是老师或者我忘了,不过就不管了吧,感觉这些都已经好多了,已经挺多的了。。

还有关于手写代码,老师说了实在不会写了可以写汉字,所以说先大概浏览一下,熟悉下流程,实在不会考试的时候就把流程写写,时间多了再仔细看代码吧,看的时候其实好多什么头文件啊这种可以不写,把关键的写上就行了,只要让老师认为你会就行了,手写代码老师挺难一眼看你写的对不对的。

就这样吧,希望大家都能考好!

by   ZY

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值