网络编程之TCP,HTTP,Socket的理解

在网络编程中,常常会接触到几个概念:TCP,HTTP,Socket。为了能区分他们之间的差异,自己做了这样的一个总结。

网络协议的层次:

TCP,HTTP都属于网络协议,但它们属于不同层次的。TCP位于传输层,HTTP位于应用层。

一、TCP:

TCP(Transmission Control Protocol) 传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层的通信协议。它是位于IP层之上,应用层之下的中间层,完成OSI模型中第四层的功能。应用层向TCP层发送网间用于传输的8位字节流。然后TCP把数据流分成一定长度的数据段,将数据包传递给IP层,IP层通过网络再将包传递给接收端的TCP层。TCP为了可靠地传输数据,每发一个包都会加个序号,接收端在成功收到一个包后会发送一个确认(ACK)。如果在发送端发送数据包的一定时间内仍没有收到接收端的确认,发送端会重新发送数据包。正是这种确认机制保证了传输的可靠性。

TCP总共有3个状态:连接创建数据传输连接终止

连接创建:TCP连接的创建需要3次握手。TCP每次握手发送数据时都会用相关的标志位来指示。这些标志位有:SYN(synchronous建立联机)、ACK(Acknowledgement确认)、PSH(Push传送)、FIN(Finish结束)、RST(Reset重置)、URG(Urgent紧急)、Sequence number(顺序号码)、Acknowledgement number (确认号码)。

第一次握手:主机A发送SYN=1,随机产生一个seq number=12341234的数据包到主机B,主机B通过syn=1确认主机A要求建立联机。

第二次握手:主机B收到请求联机信息后,会向A发送一个ack number=12341235(主机A的seq number+1),syn=1,ack=1,随机产生一个seq number=43214321的数据包。

第三次握手:主机A收到主机B发过来的ack number后先进行校验是否正确:ack number是否等于主机A的seq number+1,ack是否等于1?若正确,主机A会主机B发送ack number=主机seq+1,ack=1。主机B收到数据包确认正确后,则连接创建成功。

数据传输:TCP的数据传输采用了一些机制来保证数据的可靠性。比如:使用序号对报文段进行排序;使用校验和来检测错误;使用确认和计时器来纠正丢包或延时。

连接终止:连接终止使用了四次握手。

二、HTTP:

HTTP(HyperText Transfer protocol) 超级文本传输协议,在网络中应用最为广泛的网络协议,主要用于网页。一般情况下,一个客户端通过HTTP的向服务器的指定端口发送一个请求。然后,服务器会根据请求不发送数据或发送储存服务器的某个资源的地址。因为HTTP协议并没有规定使用它所需要下层的协议,所以HTTP下层只要保证能够提供可靠的传输,HTTP都能被应用。

了解HTTP发送的请求

通常情况下,客户端通过HTTP协议向服务器发送一个请求,即会创建一个到服务器的指定端口的连接。服务器会在相应的端口来监听来自客户端的请求,收到请求后,服务器会返回给客户端一个状态。

请求信息一般包含下面几个部分:

请求行。表示执行一个操作

空行

其它消息体

常见的请求方法(HTTP可以根据不同方法来操作服务器上的资源):

OPTIONS:返回服务器上所有资源支持的请求方法

HEAD:向服务器发送指定资源的请求。

GET:请求获取服务上指定的资源。

POST:请求服务器处理相关的数据。

PUT:向服务器传送资源。

DELETE:请求服务器删除指定位置的资源。

TRACE:测试服务器请求。

CONNECT:HTTP1.1中可将连接改为被管道的请求,主要用于SSL加密的连接。

在服务器与客户端之间进行 请求-响应时,最常用的两种方法是:GETPOST。

Get是从指定的资源请求数据。

POST向指定的资源提交要被处理的数据。

比较 GET 与 POST

下面的表格比较了两种 HTTP 方法:GET 和 POST。

  GET POST
后退按钮/刷新 无害 数据会被重新提交(浏览器应该告知用户数据会被重新提交)。
书签 可收藏为书签 不可收藏为书签
缓存 能被缓存 不能缓存
编码类型 application/x-www-form-urlencoded application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。
历史 参数保留在浏览器历史中。 参数不会保存在浏览器历史中。
对数据长度的限制 是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。 无限制。
对数据类型的限制 只允许 ASCII 字符。 没有限制。也允许二进制数据。
安全性

与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。

在发送密码或其他敏感信息时绝不要使用 GET !

POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。
可见性 数据在 URL 中对所有人都是可见的。 数据不会显示在 URL 中。

下面是关于HttpGet和HttpPost在android中应用的代码段的例子:

HttpGet:

//测试HttpGet测试方法
    private void testHttpGet() {
        try {
            //创建HttpGet对象
            HttpGet httpGet = new HttpGet("http://so.com");
            HttpClient httpClient = new DefaultHttpClient();
            //执行请求
            HttpResponse httpResponse = httpClient.execute(httpGet);
          //判断连接是否成功
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(httpResponse.getEntity());
                
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
            
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
HttpPost:

//测试HttpPost的操作方法
    private void testHttpPost() {
        //创建HttpPost对象
        HttpPost httpPost = new HttpPost("http://so.com");
        HttpClient httpClient = new DefaultHttpClient();
        try {
            //创建请求参数
            List<NameValuePair> valuePairs = new ArrayList<NameValuePair>();
            valuePairs.add(new BasicNameValuePair("par1", "device_model"));
            valuePairs.add(new BasicNameValuePair("par2", "device_company"));
            //设置字符集
            HttpEntity httpEntity = new UrlEncodedFormEntity(valuePairs, "gb312");
            httpPost.setEntity(httpEntity);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            //判断连接是否成功
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String result = EntityUtils.toString(httpResponse.getEntity());
            }
        } catch (ClientProtocolException e) {
            
            // TODO Auto-generated catch block
            e.printStackTrace();
            
        } catch (IOException e) {
            
            // TODO Auto-generated catch block
            e.printStackTrace();
            
        }
        
    }

三、Socket:

在java中,Socket一般用来实现TCP/IP协议的通信,借助socket我们实现TCP/IP协议下的数据传输。数据传输是在传输层完成的,TCP/IP协议是面向传输层的。网络上计算机要互通的话,必然要传输数据,而开发者是面向应用层的,无法直接调用TCP/IP的协议。这时他就需要一个中间者帮他实现在应用层与传输层之间传达意图。我们可以将Socket理解为,它是应用层与TCP/IP协议通信的中间软件层,相当于TCP/IP协议的接口,开发者无需关心TCP/IP协议的细节问题,在应用层就实现了TCP/IP协议数据传输的设定工作。关于Socket的使用,大家都会经常用到,不再作过多讲解了。





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值