第二课:Socket通讯与HTTP服务器

课程网站:

相关文章:

列出网络七层协议的名称,用一句话分别解释 传输层(TCP/UDP) 与 网络层(IP) 的功能。

网络七层协议:

  • 应用层
  • 表示层
  • 会话层
  • 传输层
  • 网络层
  • 数据链路层
  • 物理层

传输层(TCP/UDP)的功能:

  • 数据传送,不关心数据含义,进程间通信。
  • 弥补高层(上3层)要求与网络层(基于下3层)数据传送服务质量间的差异(差错率、差错恢复能力、吞吐率、延时、费用等),对高层屏蔽网络层的服务的差异,提供稳定和一致的界面。

网络层(IP)的功能:
TCP/IP协议栈的网络层主要负责处理主机到主机的通信,决定数据包如何交付:是交给网关(路由器)还是交给本地端口。

参考资料:
http://www.cnblogs.com/zfyouxi/archive/2014/06/22/3801899.html
http://blog.csdn.net/thisispan/article/details/7543362

Socket 在哪一层? 解释端口号的作用。

套接字(socket)编程接口是从顶上三层(网络协议的应用层,即应用层,表示层和会话层)进入传输层的接口。

IP地址和网络服务是一对多的关系。端口号可以用于区分不同的网络服务。比如21端口分配给FTP(文件传输协议)服务,25端口分配给SMTP(简单邮件传输协议)服务,80端口分配给HTTP服务,135端口分配给RPC(远程过程调用)服务等等。

参考资料:
http://www.360doc.com/content/14/0804/15/12928831_399366221.shtml
http://baike.baidu.com/link?url=wdcJm3ZrwklgGCu8foaXl0ftCUWM_IcQRWYV1XRTXcu222iJlu0qdg_VgVnqw9ONsQSyf3w3wugDPqmVXRNgia

TCP 也称 流式 Socket。 与流式文件存在联系吗?

流式文件中构成文件的基本单位是字符,流式文件是有序字符的集合,其长度为该文件所包含的字符个数,所以又称为字符流文件。流式文件无结构,且管理简单,用户可以方便地对其进行操作。源程序、目标代码等文件属于流式文件。

而TCP协议是一个传输协议,两者是完全不同领域的东西。

两者唯一可能的联系就是用TCP协议传输流式文件。因为几乎所有的文件都是由TCP协议传输的。

参考资料:
http://baike.sogou.com/v10273711.htm

阅读图2-8,连接 Socket 和 数据 Socket 相同吗?


图2-8

为什么编程时,我们通常只自定义 4 位数的端口号?

在 Java 程序中使用socket 进行通信可支持在一台主机上运行的单个服务程序为多个不同的客户程序提供服务。为实现这一目标,服务程序将选定一个固定的端口号对外发布服务客户程序则必须先按约定的主机与端口号向服务程序发送一个要求建立连接的请求(这些请求称为连接请求),申请建立一个到服务程序的连接。
服务程序在收到某一客户程序的连接请求后,并不是利用对外发布的那个端口号建立与该客户程序的连接,而是另外分配一个新的端口号建立与客户程序之间的连接,原端口号仍用于监听其他客户程序的连接请求。这一通信模式保证了服务程序对外公布的端口号仅用于处理客户程序要求建立连接的请求,不会因为该端口因长期处理客户程序的服务请求而导致其他客户程序的阻塞。

端口号的范围在065535之间。01023范围的端口号是周知端口号(well-known port number),是受限制的。Windows通常限制5000以上端口,要开启5000以上得修改注册表。所有通常是用4位数的端口号。

参考资料:
https://support.microsoft.com/zh-cn/kb/196271

文档中提到工厂方法。请用 UML 图画出 InetAddress , Inet4Address 和 Inet6Address 三者关系。

类InetAddress 采用工厂方法设计模式的好处是使客
户程序可透明地使用IPv4 协议和IPv6 协议。采用IPv4 协议时,工厂方法返回Inet4Address 的实例;采用IPv6 协议时, 工厂方法返回Inet6Address 的实例。Inet4Address 和Inet6Address 都是InetAddress 的子类。

InetAddress,Inet4Address 和 Inet6Address的关系图

对照图2.9,写出每个步骤的关键代码。


图2.9 流式Socket通信过程

侦听并等待连接:

ServerSocket listenSocket = new ServerSocket(Integer.parseInt(args[0]));
System.out.println("服务程序正在监听端口" + args[0]);
Socket socket = listenSocket.accept();

请求并建立连接:

Socket socket = new Socket(args[0], Integer.parseInt(args[1]));
System.out.println("当前socket 信息:" + socket);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

服务器建立连接:

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader
(socket.getInputStream()));

客户端发信息给服务器:

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("返回:" + in.readLine());
}
stdIn.close();

服务器接收处理信息:

String message;
while ((message = in.readLine()) != null) {
System.out.println("收到请求:" + message);
out.println(message.toUpperCase());
}

关闭连接:

out.close();
in.close();
socket.close();

(!)修改 MTEchoServer, 用 java 的 List<> 对象管理客户端连接的服务线程。当连接断开后,服务线程只是挂起。在新连接请求时,如果有挂起的服务线程,直接为新连接服务。

import java.io.*;
import java.net.*;
import java.util.ArrayList;

public class MTEchoServer {
    public static void main(String[] args) throws IOException {
        ArrayList<EchoThread> servers = new ArrayList<EchoThread>();

        if (args.length != 1) {
            System.out.println("用法:MTServer <端口号>");
            return ;
        }

        ServerSocket ss = new ServerSocket(Integer.parseInt(args[0]));
        System.out.println("服务程序正在监听端口:" + args[0]);
        for (int i = 0; i < servers.size(); i++) {
            if (servers.get(i).getState() == Thread.State.WAITING) {
                servers.get(i).notify();
                continue;
            }
            EchoThread s = new EchoThread(ss.accept());
            s.start();
            servers.add(s);
        }
    }
}

class EchoThread extends Thread {
    Socket socket;
    EchoThread(Socket s) {
        socket = s;
    }
    public void run() {
        System.out.println("正在为客户程序提供服务:" + socket);
        try {
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String message;
            while ((message = in.readLine()) != null) {
                System.out.println(socket + "请求:" + message);
                out.println(message.toUpperCase());
            }
            out.close();
            in.close();
            socket.close();
            synchronized (this) {
                try {
                    this.wait();
                } catch (InterruptedException exc) {
                    exc.printStackTrace();
                }
            }
        } catch (IOException exc) {
            exc.printStackTrace();
        }
    }
}

参考资料:
线程挂起与恢复

写出 RFC 和 IETF 的全称。 给出HTTP1.1协议的RFC编号以及全文的网址。

Request For Comments(RFC),是一系列以编号排定的文件。文件收集了有关互联网相关信息,以及UNIX和互联网社区的软件文件。目前RFC文件是由Internet Society(ISOC)赞助发行。基本的互联网通信协议都有在RFC文件内详细说明。RFC文件还额外加入许多的论题在标准内,例如对于互联网新开发的协议及发展中所有的记录。因此几乎所有的互联网标准都有收录在RFC文件之中。
国际互联网工程任务组(The Internet Engineering Task Force,简称 IETF)是一个公开性质的大型民间国际团体,汇集了与互联网架构和互联网顺利运作相关的网络设计者、运营者、投资人和研究人员,并欢迎所有对此行业感兴趣的人士参与。

参考资料:
百度百科 RCF
百度百科 IETF
IETF官网 RFC文档

阅读 Daytime 协议开发,简单解释图 2-11 的含义。它对程序阅读的作用。


图 2-11 程序DaytimeTCP 客户端与服务器程序类图

DaytimeServer2是基于TCPDaytime服务器程序,首先通过ServerSocket 类的实例化产生流
Socket,并由MyStreamSocket 类的实例对象的accept()方法监听客户端请求,等待客户端连
接。当收到客户端请求后,由sendMessage()方法返回消息给客户端。

MyStreamSocket类继承Socket 类,setStreams()方法得到数据输入流InputStream 与输出流OutputStream , sendMessage() 方法发送数据流,receiveMessage() 接收数据流。

DaytimeClient2是基于TCPDaytime 客户端程序,客户端程序从命令行取得服务端的地址与端
口,通过客户端帮助类DaytimeClientHelper2 的getTimestamp()方法向服务端发送请求并接收
响应消息。

DaytimeClientHelper2客户端帮助类创建MyStreamSocket类的实例对象mySocket,由实例对象的
receiveMessage()方法接收服务端的响应消息。

图2-11说明了这几个类之间的关系。DaytimeClient2用到了DaytimeClientHelper2的实例,DaytimeClientHelper2用到了MyStreamSocket的实例,DaytimeServer2用到了ServerSocket和MyStreamSocket的实例,而MyStreamSocket继承自Socket类。用这样的UML图可以使得类与类之间的关系更加清楚。

编程序经常会编写xxHelper 类,请描述 DaytimeTCP 程序中,DaytimeClientHelper2类发挥的作用。

有模块化思想,实现了类的封装性,有利于代码的维护和复用

运行 java 版本 HttpServer。设计3个curl 指令,测试程序的三种输出响应,给出控制台输入与输出。

由于默认是80端口,被占用,于是改成了2000端口。

ServerSocket ss = new ServerSocket((args.length == 0) ? 2000 : Integer.parseInt(args[0]));
打开HttpServer客户端

在服务器文件夹下添加一个index.html,输入curl localhost:2000

curl localhost:2000

输入一个不存在的网页,例如curl localhost:2000/notfound

404

就出现了404的提示。由于Java的编码问题,出来了一堆乱码。但是可以看懂有404。如果直接用浏览器打开,则没有这个问题。

如果用Post方法,例如输入curl -d "400 Test" localhost:2000

400

则出现了400提示,表示非法请求。


(!)阅读 “课后完成设计实验 HTTP 学号尾数为奇数同学完成.pdf”
improveHTTPServer 设计者的目标是什么?用了哪些手段改进了程序设计?

  • 改进单线程服务器为多线程服务器,实现并发处理请求;
  • 综合应用设计模式(工厂方法、模板方法、策略模式、Facade 模式、责任链模式等),构建可扩展的Web 服务器。

如果要实现 POST 方法,如何改程序(改哪个类)?

……

(!!)尝试给出处理不同请求方法的 UML 设计图。
……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,252评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,886评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,814评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,869评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,888评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,475评论 1 312
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,010评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,924评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,469评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,552评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,680评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,362评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,037评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,519评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,621评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,099评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,691评论 2 361

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,713评论 18 139
  • 18.1 引言 TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本章将...
    张芳涛阅读 3,390评论 0 13
  • 20171002 周一 心赏第49天 亲爱的康夫君,今天我建议你找合适的机会和yo深层次的沟通并且向她道歉,孩子的...
    静夜思CJ阅读 209评论 0 1
  • 辩论 准备 3 2 1 马上 下次 开始!
    浣熊阅读 203评论 0 0
  • 之前已经对我们学习插件化原理需要的预备知识进行了比较详细的讲解了,从这篇文章开始,我们将具体介绍插件化原理,同时会...
    小之丶阅读 2,844评论 1 21