java的服务端与客户端通信(2)
一、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)的更多相关文章
- java的服务端与客户端通信(1)
一.理解socket 1.1什么是socket? socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络 ...
- Netty 学习(二):服务端与客户端通信
Netty 学习(二):服务端与客户端通信 作者: Grey 原文地址: 博客园:Netty 学习(二):服务端与客户端通信 CSDN:Netty 学习(二):服务端与客户端通信 说明 Netty 中 ...
- C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
Winform窗体实现服务端和客户端通信的例子,是参考这个地址 http://www.cnblogs.com/longwu/archive/2011/08/25/2153636.html 进行了一些异 ...
- Java TCP服务端向客户端发送图片
/** * 1.创建TCP服务端,TCP客户端 * 2.服务端等待客户端连接,客户端连接后,服务端向客户端写入图片 * 3.客户端收到后进行文件保存 * @author Administrator * ...
- (C#:Socket)简单的服务端与客户端通信。
要求:1.可以完成一对一的通信:2.实现服务端对客户端一对多的选择发送:3.可以实现服务端的群发功能:4.可以实现客户端文件的发送: 要点:服务器端:第一步:用指定的端口号和服务器的ip建立一个End ...
- C# Socket服务端与客户端通信(包含大文件的断点传输)
步骤: 一.服务端的建立 1.服务端的项目建立以及页面布局 2.各功能按键的事件代码 1)传输类型说明以及全局变量 2)Socket通信服务端具体步骤: (1)建立一个Socket (2)接收 ...
- java网络编程-单线程服务端与客户端通信
该服务器一次只能处理一个客户端请求;p/** * 利用Socket进行简单服务端与客户端连接 * 这是服务端 */public class EchoServer { private ServerSoc ...
- 【转】C# client 与java netty 服务端的简单通信,客户端采用Unity
http://blog.csdn.net/wilsonke/article/details/24721057 近日根据官方提供的通信例子自己写了一个关于Unity(C#)和后台通信的类,拿出来和大家分 ...
- 多线程服务端与客户端通信(IO是阻塞的)_02
下面是多线程的;每次服务端接受请求,会创建一个线程专门处理这个请求: 虽然是多线程的,但还是阻塞,相当于单线程处理模式 public class TimeServer { public static ...
随机推荐
- iOS开发-常用第三方开源框架介绍
iOS开发-常用第三方开源框架介绍 图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网 ...
- Redis的README.md
This README is just a fast *quick start* document. You can find more detailed documentation at http: ...
- sqrt函数实现(神奇的算法)
我们平时经常会有一些数据运算的操作,需要调用sqrt,exp,abs等函数,那么时候你有没有想过:这个些函数系统是如何实现的?就拿最常用的sqrt函数来说吧,系统怎么来实现这个经常调用的函数呢? 虽然 ...
- Eclipse Debug 调试
Debug 调试 Java 程序 我们可以在 Package Explorer 视图调试 Java 程序,操作步骤如下: 鼠标右击包含 main 函数的 java 类 选择 Debug As > ...
- 安装VC6.0遇到的问题
1. 问题现象 安装VC6.0后,又安装了VS2005.用VC6.0打开以前的.dsw文件时,程序自动关闭.如下图所示. 具体操作是:选择一个.dsw文件,右键菜单[打开方式]中选择[Microsof ...
- 【转】ATL提供的所有转换宏
在头文件<atlconv.h>中定义了ATL提供的所有转换宏,如: A2CW (LPCSTR) -> (LPCWSTR) A2W (LPCSTR) -> (LPWSTR ...
- ios . -- UICollectionView --cell 自适应
#pragma mark — 视图控制器中使用:(关键) layout.estimatedItemSize = CGSizeMake(WIDTH, ); // layout约束这边必须要用estima ...
- iOS - 逆向 - Objective-C代码混淆 -confuse.sh文件写法
class-dump可以很方便的导出程序头文件,不仅让攻击者了解了程序结构方便逆向,还让着急赶进度时写出的欠完善的程序给同行留下笑柄. 所以,我们迫切的希望混淆自己的代码. 混淆的常规思路 混淆分许多 ...
- final和finally面试时最好的回答
finally: try块必须和catch块或和finally同在,不能单独存在,二者必须出现一个. finally块总会执行,不论是否有错误出现.但是若try语句块或会执行的catch语句块使用了J ...
- redhat 配置本地yum源163yum源epel 源,无需卸载yum!无须拷贝ISO
都知道redhat不收费,但是其yum服务是要收费的,不想出钱那就自己配置yum源就好了. 首先,博主之前也没用过redhat,第一次用yum装包的时候提示什么没注册之类的,balaba一大堆,然后就 ...