Talk is cheap,用代码告诉你Http和Tcp的关系

本人菜鸟一枚,在此之前,我经常看到的一句话是“HTTP是基于TCP的”,但是,对于我这等菜鸟来说,实在太过高深。

没想到看了How Tomcat Works的第一章第一节的代码示例,我似乎明白了二者的关系。带着疑问,写了如下代码,来验证自己的设想。

首先,使用java的socket模拟client,注意不是使用httpclient这种封装好的工具。
执行之后,控制台输出了页面的源码。

代码如下
public class SimpleHttpClient {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("www.haosou.com", 80);

PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "utf-8"));

writer.println("GET / HTTP/1.1");
writer.println("Host: www.haosou.com");
writer.println("Connection: keep-alive");
writer.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
writer.println("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36");
writer.println("Accept-Language: zh-CN,zh;q=0.8");

writer.println(); // 木有这一行,阻塞

String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}

writer.close();
reader.close();
socket.close();
}
}


页面源码,如下
....
<script>LS.html2ls("stc_home_foot_js","stc_home_foot_js")</script>

</body>
</html>
篇幅原因,捧场的小伙伴可以自己跑下代码看一下。

如此,我基本验证了自己的猜想:Http是基于文本解析的约定,TCP负责传输

为了进一步验证,我又用Java的ServerSocket写了一个简陋的HttpServer,

启动该Server,也就是运行该代码,打开浏览器,在地址框输入http://localhost?name=Tom
可以看到页面显示了一个Tom的超链接,点击它,跳转到百度搜索的Tom页,当然,你可以不用Tom,而是用Jerry

代码如下,比较粗糙,将就看吧
public class SimpleHttpServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(80);
while (true) {
Socket socket = server.accept();
new Task(socket).start();
}
}
}

class Task extends Thread {
private Socket socket;

public Task (Socket socket) {
this.socket = socket;
}

public void run () {
try {
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "utf-8"));

// 获取请求中的参数, 忽略header神马的
String firstLine = reader.readLine();
String name = parseName(firstLine);
System.out.println("name:" + name);

writer.println("<html>");
writer.println("<body>");
writer.println("<a href=\"https://www.baidu.com/s?wd=" + name +"&rsv_spt=1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=1&rsv_pq=9f77f8020000142e&rsv_t=af959DHMVRjqn9YFbiJw6m4svc%2Bs125HBrbqHOXkBFUxxNS4zBQgMjxhX1xr4cGzySAr&inputT=900&rsv_sug3=22&rsv_sug1=21&rsv_sug2=0&rsv_sug4=900\">" + name + "</a>");
writer.println("</body>");
writer.println("</html>");
writer.println();
}catch (Exception e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

private String parseName(String line) {
String query = line.substring(line.indexOf("?") + 1);
query = query.substring(0, query.indexOf(" "));

return query.split("=")[1];
}

public Socket getSocket() {
return socket;
}

public void setSocket(Socket socket) {
this.socket = socket;
}
}


好了,这就是我目前理解到的Http和TCP的关系:如果用快递做比喻的话,卖家发货给买家是http请求,宝贝是http内容,快递公司是tcp,卖家和买家知道宝贝的详情,而快递公司不需要知道是什么,只负责传输,买卖方也无需关注快递细节。这个和其他网络分层是一样的——下层无需关注上层的内容,逻辑上,就像两个http直接对话。希望这个比喻,能给小伙伴的理解带来一定帮助。

附件中是我写的两个类,感兴趣的同学可以下载下来,木有额外的依赖,只用到JDK的包,改下package,就能运行

能力有限,多多指教。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值