一、Socket连接与HTTP连接

  1.1Socket套接字

  • 套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
  • 应用层通过传输层进行数据通信时,TCP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

  1.2Socket与TCP连接

  • 创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议(TCP或UDP),当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。

  1.3Socket连接与HTTP连接

  • 由于通常情况下Socket连接就是TCP连接,因此Socket连接一旦建立,通信双方即可开始相互发送数据内容,直到双方连接断开。但在实际网络应用中,客户端到服务器之间的通信往往需要穿越多个中间节点,例如路由器、网关、防火墙等,大部分防火墙默认会关闭长时间处于非活跃状态的连接而导致 Socket 连接断连,因此需要通过轮询告诉网络,该连接处于活跃状态。
  • 而HTTP连接使用的是“请求—响应”的方式,不仅在请求时需要先建立连接,而且需要客户端向服务器发出请求后,服务器端才能回复数据。
  • 很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。

  1.4TCP和UDP的区别

  • TCP是面向链接的,虽然说网络的不安全不稳定特性决定了多少次握手都不能保证连接的可靠性,但TCP的三次握手在最低限度上(实际上也很大程度上保证了)保证了连接的可靠性;而UDP不是面向连接的,UDP传送数据前并不与对方建立连接,对接收到的数据也不发送确认信号,发送端不知道数据是否会正确接收,当然也不用重发,所以说UDP是无连接的、不可靠的一种数据传输协议。
  • 也正由于1所说的特点,使得UDP的开销更小数据传输速率更高,因为不必进行收发数据的确认,所以UDP的实时性更好。

知道了TCP和UDP的区别,就不难理解为何采用TCP传输协议的MSN比采用UDP的QQ传输文件慢了,但并不能说QQ的通信是不安全的,因为程序员可以手动对UDP的数据收发进行验证,比如发送方对每个数据包进行编号然后由接收方进行验证啊什么的,即使是这样,UDP因为在底层协议的封装上没有采用类似TCP的“三次握手”而实现了TCP所无法达到的传输效率。

  1.5传输层与应用层协议

  • 我们在B/S或C/S架构下传输数据时,可以使用传输层协议(TCP/IP),也可以使用应用层协议(HTTP,FTP)。但如果我们只是用传输层协议,没有应用层,便无法识别数据内容,要使我们传输的数据有意义,必须用到一个应用层协议,我们也可以自己定义应用层协议。WEB应用程序使用HTTP协议作应用层协议,以封装HTTP文本信息,然后使用TCP/IP作为传输层协议将它发到网络上。
  • Socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API),通过Socket,我们才能使用TCP/IP协议。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而形成了我们知道的一些最基本的函数接口。而HTTP连接时建立在传输层基础之上的。

总而言之,HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。

二、用Socket模拟客户端向真实服务端发送请求

  2.1HTTP请求格式

    <request-line>
    <headers>
    <blank line>
    [<request-body>]

(1)GET请求

GET/ sample.jsp HTTP/1.1                               请求方法  URI  协议/版本
Accept: image/gif.image/jpeg,*/*              浏览器可接受的MIME类型
Accept-Language: zh-cn                    浏览器所希望的语言种类,当服务器能够提供一种以上的语言版本时要用到(发送参数时有个参数q,表明用户的喜好程度)
Connection: Keep-Alive                    Connection:表示是否需要持久连接。
Host: localhost                        初始URL中的主机和端口
User-Agent: Mozila/4.0(compatible;MSIE5.01;Window NT5.0)浏览器类型(如果Servlet返回的内容与浏览器类型有关则该值非常有用)
Accept-Encoding: gzip,deflate                浏览器能够进行解码的数据编码方式(Servlet能够向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这可以减少5到10倍的下载时间。) username=jinqiao&password=1234              

 (2)POST请求

POST / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded     说明了请求主体的内容是如何编码的,这是针对简单URL编码的MIME类型。
Content-Length: 40                      表示请求消息正文的长度。
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley

   2.2HTTP响应格式

如下所示,HTTP响应的格式与请求的格式十分类似:

<status-line>
<headers>
<blank line>
[<response-body>]

正如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。以下就是一个HTTP响应的例子:

HTTP/1.1 200 OK                                        状态行给出的HTTP状态代码是200,以及消息OK。状态行始终包含的是状态码和相应的简短消息,以避免混乱
Date: Sat, 31 Dec 2005 23:59:59 GMT            用来说明响应生成的日期和时间(服务器通常还会返回一些关于其自身的信息,尽管并非是必需的)。
Content-Type: text/html;charset=ISO-8859-1        指定了MIME类型HTML(text/html),其编码类型是ISO-8859-1(这是针对美国英语资源的编码标准)
Content-Length: 122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>
常用的状态码有:
◆200 (OK): 找到了该资源,并且一切正常。
◆304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
◆401 (UNAUTHORIZED): 客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
◆403 (FORBIDDEN): 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
◆404 (NOT FOUND): 在指定的位置不存在所申请的资源。
* 1XX 保留 
* 2XX 表示成功 
* 3XX 表示URL已经被移走 
* 4XX 表示客户错误 
* 5XX 表示服务器错误 

  2.3模拟客户端向真实服务端发送请求(Socket版)

客户端代码:

 1 package socketPractiseList;
2
3 import java.io.*;
4 import java.net.*;
5 public class HttpClient {
6
7 public static void main(String args[])throws Exception{
8 InetAddress inet=InetAddress.getByName("www.baidu.com");
9 System.out.println(inet.getHostAddress());
10 Socket socket=new Socket(inet.getHostAddress(),80);
11 InputStream in=socket.getInputStream();
12 OutputStream out=socket.getOutputStream();
13 BufferedReader reader=new BufferedReader(new InputStreamReader(in));
14 PrintWriter writer=new PrintWriter(out,true);
15 writer.println("GET /home.html HTTP/1.1");//home.html是关于百度的页面
16 writer.println("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjeg, application/xaml+xml,"
17 +"application/vnd.ms-xpdocument, application/x-ms-xbap,application/x-ms-application,"
18 +"application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint,*/*");
19 writer.println("Accept-Language:en-us,zh-cn;q=0.5;");
20 writer.println("Content-Type:text/html;");
21 writer.println("Accept-Encoding:gzip,deflate;");
22 writer.println("Host:www.baidu.com");
23 writer.println("User-Agent:Mozilla/4.0(compatible;MSIE6.0;windows NT5.1;SV1;.NET CLR 1.1.4322;.NET CLR 2.0.50727;"
24 + ".NET CLR 3.0.04506.30;.NET CLR 3.0.4506.30;.NET CLR 3.0.4506.30;.NET CLR 3.0.4506.2152;.NET CLR 3.5.30729)");
25 writer.println("Connection:Keep-Alive");
26 writer.println();
27 writer.flush();
28 String result=reader.readLine();
29 while(result!=null){
30 System.out.println(result);
31 result=reader.readLine();
32 }
33 reader.close();
34 writer.close();
35 socket.close();
36 }
37 }

服务端的响应信息:

乱码问题估计有两种解决方式:(1)指定字符集编码方式;(2)不用BufferedReader,改用DataInputStream;(3)使用缓冲字节流;

2.4模拟客户端向真实服务端发送请求(HTTPClient版)

java的服务端与客户端通信(2)的更多相关文章

  1. java的服务端与客户端通信(1)

    一.理解socket 1.1什么是socket? socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...

  2. Netty 学习(二):服务端与客户端通信

    Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...

  3. C#Winform窗体实现服务端和客户端通信例子(TCP/IP)

    Winform窗体实现服务端和客户端通信的例子,是参考这个地址 http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html 进行了一些异 ...

  4. Java TCP服务端向客户端发送图片

    /** * 1.创建TCP服务端,TCP客户端 * 2.服务端等待客户端连接,客户端连接后,服务端向客户端写入图片 * 3.客户端收到后进行文件保存 * @author Administrator * ...

  5. (C#:Socket)简单的服务端与客户端通信。

    要求:1.可以完成一对一的通信:2.实现服务端对客户端一对多的选择发送:3.可以实现服务端的群发功能:4.可以实现客户端文件的发送: 要点:服务器端:第一步:用指定的端口号和服务器的ip建立一个End ...

  6. C# Socket服务端与客户端通信(包含大文件的断点传输)

    步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤:   (1)建立一个Socket   (2)接收 ...

  7. java网络编程-单线程服务端与客户端通信

    该服务器一次只能处理一个客户端请求;p/** * 利用Socket进行简单服务端与客户端连接 * 这是服务端 */public class EchoServer { private ServerSoc ...

  8. 【转】C# client 与java netty 服务端的简单通信,客户端采用Unity

    http://blog.csdn.net/wilsonke/article/details/24721057 近日根据官方提供的通信例子自己写了一个关于Unity(C#)和后台通信的类,拿出来和大家分 ...

  9. 多线程服务端与客户端通信(IO是阻塞的)_02

    下面是多线程的;每次服务端接受请求,会创建一个线程专门处理这个请求: 虽然是多线程的,但还是阻塞,相当于单线程处理模式 public class TimeServer { public static ...

随机推荐

  1. Redis入门经典——The Little Redis Book (翻译)

    The Little Redis Book By Karl Seguin 关于本书:本书全然免费下载.你能够任意转载,复制.但请你注明作者.Karl Seguin.译者,WY. 以及不要用于商业用途. ...

  2. IOS设计模式浅析之适配器模式(Adapter)

    引言 在项目开发中,有时候会遇到这样的一种情景:需要使用以前开发的“一些现存的对象”,但是新环境中要求的接口是这些现存对象所不满足的.怎样应对这种迁移的需求?使得可以复用这些对象,以满足新的应用环境, ...

  3. easy_UI datagrid view数据格式化

    从数据库中提取的信息,有时候需要后期处理一下,easy_ui给了我们很好的一个方法,根据easy_ui生成datagridview的两种方式,下面用两种方式来格式化显示数据信息 1,通过脚本生成的da ...

  4. Redis的Aof被阻塞原因调查

    背景 Redis是单进程的,为了发挥多核的优势,我们redis集群采用在单台机器上部署多个redis实例,同时对持久化方式做了改进,采用rdb和增量的aof相结合的方式,appendfsync配置为n ...

  5. cobbler 更换dns和dhcp服务器为dnsmasq

    1) 需要配置/etc/cobbler/module.conf, 把manage_dns和manage_dhcp改为manage_dnsmasq 2) 重启cobbler和dnsmasq服务,dnsm ...

  6. UML Rose2003完美破解攻略

    Rational Rose 2003 软件project画图软件 ,当然还不止画图,对于那些不想用英文版Rational Rose2003的同志们.这个Rational Rose2003 版本号已经汉 ...

  7. js 数组容易弄混的那些方法

    js数组中 我们很多数组的方法都知道其中的含义 但是每一次用的都不是很顺手 下边我给大家写了一个小小的demo 来理解那些 近似”双胞胎“的东西 // splice方法 var a=[1,2,3,4, ...

  8. laravel类自动注释

    github地址:https://github.com/barryvdh/laravel-ide-helper php artisan ide-helper:models --dir="pa ...

  9. Quartz.NET 作业调度

    Quartz 简介: Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调 ...

  10. 使用bbed编辑研究oracle数据块结构

    bbed是随oracle软件公布的一款数据块查看和编辑工具,作为一款内部工具.bbed的功能很强大,可是假设使用不当可能给数据库造成无法挽回的损失.因此.我们建议在使用bbed改动数据块前备份被改动的 ...