`

黑马程序员Java培训和Android培训Java Web 网络编程

 
阅读更多
黑马程序员

网络编程

网络编程的基础知识
网络协议TCP/IP
网络协议规定了计算机之间连接的物理,机械,电气等特性以及计算机之间的相互寻址规则,数据发送冲突的解决办法,分段发送与接收大数据包的方式等等。计算机之间连接的机械特性包括网线与网卡之间的连接规则,计算机之间连接的电气特性就是指电平范围。

IP地址和Port(端口号)
IP地址就是计算机在网络中的唯一标志号。是四个字节的整数表示的被称之为IPV4。为了方便记忆,用每个字节表示的整数加小圆点的格式来表示。
本地回路的IP地址:127.0.0.1 发送到此地址的信息不经过网卡传递,而是直接被本地的TCP/IP协议栈中的几个上层协议接收。使用 ping 127.0.0.1就可以查看本地TCP/IP协议是否被正确安装。
用十六个字节表示IP地址,这就是IPV6。
一台计算机中可以运行多个网络程序,IP地址只能将数据发送到那个计算机中,而不能知道发送到哪个网络程序中。因此在每一个被发送的数据包头部都包含有一个被称之为端口(Port)的部分。Port是一个占有两个字节的整数。用来表示将数据包发给哪个程序来处理。必须也在程序中指定一个端口号,用来告诉应该接收哪个端口的数据包。不同应用程序接收不同端口上的数据。同一台计算机中不能存在同时使用一个端口的两个程序运行。端口号的范围为0-65535之间,0-1023之间的端口数是用于一些知名的网络服务和应用。
网络通信与其说是两台计算机之间在通信,不如说是两台计算机内的应用用程序之间的通信。但是这两个程序要使用不同的端口号。


UDP与TCP
TCP,传输控制协议(Transmission Control Protocol),是面向连接的通信协议。提供两台计算机可靠,无差错的数据传输。应用程序利用TCP进行数据传输时,数据源与接收目标之间会建立一个虚拟的连接。这样的连接一旦建立,数据源与接收目标就会将数据当作一个双向的字节流进行交换。

UDP,用户数据报协议(User Datagram Protocol),是无连接的通信协议。UDP不保证数据的可靠传输。但能够向若干个目标发送数据,和接收若干个发自于源的数据。
另外在网络线路繁忙时或发生故障时会发生数据报的丢失。一台计算机如果接收到一条数据,不会确认收到与否。

TCP,UDP的数据帧格式简单图例:(方括号代表方框,方括号是连接在一起的。)
[协议类型][源IP][目标IP][源端口][目标端口][帧序号][帧数据]
其中协议类型用于区分TCP,UDP

Socket
Socket是网络驱动层提供给应用程序编程的接口和一种机制。

可以把Socket比喻成是一个港口码头。应用程序只要把货物放到港口码头上,就算完成了货物的运送。应用程序只需等待货物到达码头后,将货物取走。

Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉自己所对应的IP和Port。

Socket数据发送过程如图:


Java中的网络编程类

位于java.net包中
DatagramSocket类用于UDP通信。
ServerSocket类用于TCP通信的服务器端。
对于只有一个IP地址的计算机一般不用指定IP地址。
Socket类用于TCP通信的服务器和客户端。
UDP网络程序
TCP网络程序
访问Internet网络资源

UDP网络程序
DatagramSocket类

构造函数:
--public DatagramSocket()
--public DatagramSocket(int port)
--public DatagramSocket(int port,InetAddress laddr)

close方法:关闭DatagramSocket对象。

send(DatagramPacket p)方法用于发送DatagramPacket。
receive(DatagramPacket p)方法用于接受DatagramPacket。

DatagramPacket类
如果把DatagramSocket比作创建的港口码头,那么DatagramPacket就是发送和接收数据的集装箱。
构造函数:
public DatagramPacket(byte[] buf,int length)
public DatagramPacket(byte[] buf,int length,InetAddress address,int port)

getInetAddress和getPort方法
getData和getLength方法




InetAddress类
InetAddress是用于表示计算机IP地址的一个类,而在日常应用中的计算机地址是用"192.168.0.1","www.it315.org"等字符串来表示的。

getByName方法



最简单的UDP程序
字符串与字节数组之间的双向转换。
UDP接收程序必须先启动运行,才能接收UDP发送程序发送的数据。
用start命令来打开新命令行窗口的好处。
解决发送中文字符串的问题。
注意啦:在拼写IP地址成为字符串时,不能有多余的空格。
发送数据出现丢失的原因:当出现中文字符时,将它转换成字节的时候,它占两个字节的空间。而程序中的new DatagramPacket() 的参数中的length 代表包数据长度,它是以字节为单位的,它获得的长度要小于要发送的带有中文的字符串转换成字节的个数,所以发生丢失。解决办法就是先将字符串转换成字节再调用length。

用UDP编写网络聊天程序


用UDP编写网络聊天程序
用广播地址也可以。


用UDP编写网络聊天程序
文件夹中有图:
分为三个步骤来完成:
1编写图形用户界面;
2编写网络消息发送功能;
3编写网络消息接收功能。
几个问题:
1这个网络程序能够自己给自己发送数据吗?可以。
2如何发送广播数据?利用192.168.0.255为广播地址来进行发送广播数据。只有UDP程序可以发送和接收广播数据。
3这个程序可以在Internet上用吗?使用私有IP并通过网关代理上网的计算机呢?
可以放在Internet上使用的;但是使用私有IP并通过网关代理上网的计算机不能和具有合法的IP地址进行通信。


TCP网络程序
TCP网络程序的工作原理
TCP客户端程序与TCP服务器端程序的交互过程:
(1)服务器程序创建一个ServerSocket,然后调用accept方法等待客户来连接。
(2)客户端程序创建一个Socket并请求与服务器建立连接。
(3)服务器接收客户的连接请求,并创建一个新的Socket与客户建立专线连接。
(4)建立了连接的两个Socket在一个单独的线程(由服务器程序创建)上对话。
(5)服务器开始等待新的连接请求,当新的连接请求到达时,重复步骤(2)到步骤(5)的过程。

ServerSocket类
存在与java.net包中。
构造函数:
--public ServerSocket()  需要bind方法才可以使用
--public ServerSocket(int port) 默认的backlog是50
--public ServerSocket(int port,int backlog) backlog代表在服务器很忙的时候,等待的客户数量。
--public ServerSocket(int port,int backlog,InetAddress bindAddr)

当不使用ServeerSocket时应调用close方法将其关闭。
调用accept方法等待对客户端连接的请求。

Socket类(不能使用该类的构造函数来创建服务器端的Socket对象)
构造函数:
--public Socket()
--public Socket(String host,int port)//经常使用这个构造函数来创建Socket对象。
--publc Socket(InetAddress address,int port)
--public Socket(String host,int port,InetAddress localAddr,int localPort)//有多快网卡时才可能用到这个构造函数。
--public Socket(InetAddress address,int port,InetAddress localAddr,int localPort)

getInputStream和getOutputStream方法
一旦客户端Socket与服务器端Socket连接成功,就会以字节流的形式传送数据。getInputstream方法返回输入流;getOutputStream方法返回输出流。


简单的TCP服务程序
TCP服务器程序必须先启动运行,TCP客户程序才能连接上TCP服务器。
使用Windows提供的telnet程序测试TCP服务器程序。
使用BufferReader包装类,从网络输入流中一次读取一行文本。
如何打开telnet程序的本地回显功能。(telnet就是Windows自带的TCP客户端程序)

完善的TCP服务程序模型
TCP客户端程序
如何检测和解决端口冲突问题
通过TCP程序在网络上传递对象


完善的TCP服务器程序模型
编程实例:
服务器程序能够同时与多个客户端会话,客户端每次向服务器发送一行字符文本,服务器就将这行字符文本中的所有字符方向排列后回送给客户端,当客户端向服务器发送的一行字符文本内容为"quit"时,服务器结束与客户端的会话。

注意:I/O输入是有个缓冲区的。它不一定真正的写入到底层设备中。
退格键也会占用字符。

以上的服务器程序模型也适用于http,smtp,pop3,ftp,各种服务器程序不同之处在于所会话的内容不同。也就是Servicer中while循环中的语句不同。
printWriter的println()方法可以打印出与操作系统相关关的的换行符。即windows下的换行符为"\r\n",Linux下是"\n";printerStream的println方法打印换行符"\n"与操作系统无关。
编写TCP服务器程序模型的编写要点:
--TCP服务器程序要想接收多个客户端连接,需要循环调用ServerSocket.accept方法。
--服务器程序与每个客户端连接的会话过程不能互相影响,需要在独立的线程中运行。
--一个线程服务对象与一个服务器端Socket对象相关联,共同来完成与一个客户端的会话。


如何检测和解决端口冲突问题
使用netstat命令查看当前正在被使用的TCP端口号。
通过一个配置参数来指定TCP服务程序所使用的端口号。
将用户所指定的端口号保存到一个文件中,当服务器程序下次启动运行时,直接从文件中读取那个端口号。(为了将该服务器程序做的更友好而采取的措施)。

TCP客户端程序
编程实例:
  编写一个与上面的服务器程序通信的客户端程序。
要点:
  连接服务器的IP地址和端口号不要固定编写在程序代码中,而是通过程序的运行时参数来指定,以提供较好的灵活性和较高的通用性。


在TCP网络连接上传递对象
ObjectInputStream和ObjectOutputStream可以从底层输入流 读取对象类型的数据和将对象类型的数据写入到底层输出流。

使用ObjectInputStream和ObjectOutputStream来包装底层网络字节流,TCP服务器和TCP客户端之间就可以传递对象类型的数据。

编程实例:通过网络传输Java对象。

怎样理解应用程序协议和网络通信协议的关系
TCP协议可以保证两台计算机之间进行通信,但是不保证接收方可以理解发送发发送的内容。ftp协议是建立在TCP协议之上的,是用在网络上传输文件的。ftp,smtp等都是应用程序协议。

怎样区分ASP,JSP与网络编程的概念
ASP,JSP只是为了编写网站内容的。而不是编写网络程序的。


访问Internet网络资源
java.net包中还有URL,URLDecoder,URLEncoder,URLConnection,HttpURLConnection等类。

URL(统一资源定位符)
URL(Uniform Resource Locator),可以是一个文件或目录,也可以是一个复杂的对象。
URL的基本组成:协议,主机名,端口号,资源名。例如,http://www.it315.org:8080/index.html,其中http是协议部分规定了通信会话方式及数据格式,www.315.org是主机名  8080是端口号   index.html是资源名
每个协议都有默认的端口号比如http的默认端口号是80,url通常都是大小写敏感的。

很多情况下要使用相对URL:例如"/a.html","/a.html","../../a.html","a.html"。
来增加应用的灵活性。/开头表示主机目录下的某种协议的根目录;以../开头表示当前资源所在目录的父目录;以../../开头表示父目录的父目录;直接使用文件名或者目录名则表示当前目录下的子目录或文件。以./开头或者直接使用文件名作用是一样的。相对URL不包括协议和主机名,它表示路径与当前文档或Internet网络资源访问协议主机名相同甚至有相同的目录路径。一个完整的URL可以由基准URL和相对URL组成。

URL编码规则:因为利用http协议对于某些字符是不能传送的,所以要用URL编码规则。编码遵循以下规则
---将空格转换为加号(+)
---对于0-9,a-z,A-Z之间的字符保持不变。
---对于所有其他的字符,用这个字符的当前字符集编码在内存中的十六进制格式表示,并在每个字节前加上一个百分号(%)。如字符"+"用%2B表示,字符"="用%3D表示,字符"&"用%26表示,每个中文字符在内存中占用两个字符,字符"中"用%D6%D0表示,字符"国"用%B9%FA表示。
---对于空格也可以直接使用其十六进制编码方式,即用 %2D表示,而不是将它转换成加号(+)。

java.net包中提供了URLEncoder和URLDecoder这两个类,来实现URL编码和解码。

HTTP协议
定义了WEB浏览器和WEB服务器之间交换数据的会话过程以及数据本身的格式。http1.1比http1.0的最大优点就是支持长久的连接。

HTTP消息请求
一个完整的请求消息包括:一个请求行,若干消息头,以及实体内容。其中消息头和消息行是可选的。例如:
GET/articles/news/today.asp HTTP/1.1     //必不可少
Accept:*/*
Accept-Language:en-us
Connection:Keep-Alive                     //一般设置为Connection:close
Host:localhost     //必不可少的,如果是虚拟机还要返回域名
Refer:http://localhost/link.asp
User-Agent:Mozilla/4.0(compatible;MSIE5.5;Windows NT5.0)
Accept-Encoding:gzip,deflate


HTTP响应消息
一个完整的响应消息包括:一个状态行,若干消息头,以及实体内容。
例如:
HTTP/1.1 200 OK
Server:Microsoft-IIS/5.0
Data: Thu,13 Jul 2000 05:46:53 GMT
Content-Type: text/html
set-Cookie:ASPSESSIONIDQQGGGNCG=LKLDFFKCINFLDMFHCBCBMFLJ;path=/
Cache-control:private

<HTML>
<BODY>
......


了解几个HTTP消息头
Connection
用于指定处理完本次请求/响应后,客户端与服务器是否继续保持连接。设置值可以为Keep-Alive和close。

Accept-Language
用于指出客户机期望服务器返回的文档所使用的的国家语言,可以指定多个以逗号分隔的国家语言。

Content-Length
用于表示实体内容的长度(字节数)。

Range(可用于断点续传)
用于指定服务器只需返回文档中的部分内容及内容范围,有以下几种使用格式:
(1)Range: byte=100-599
(2)Range: byte=100-
(3)Range: byte=-100

Content-Range(与Range配对使用)
用于指定服务器返回的部分实体内容的位置信息,例如,
Content-Range: byte 2543-4532/7898  //7898是指整个信息的大小是7898字节。
URL类
工厂设计模式
URLConnection和HttpURLConnection类


URL类
构造函数(都可引发MalformedURLException异常):
---public URL(String spec)
---public URL(String protocol,String host,int port,String file)
---public URL(String protocol,String host,int port,String file,URLStreamHandler handler)
---public URL(URL contex,String spec)

getProtocol,getHost,getPort,getFile等方法。
getConnection调用协议处理器(URLStreamHandler)返回一个URLConnection对象。


工厂设计模式
URL类的setURLstreamHandlerFactory(URL StreamHandlerFactory fac)静态方法。StreamHandlerFactory用于建立协议名与协议处理器的对应关系。
StreamHandlerFactory类的createURLStreamHandler(String protocol)方法。


URLConnection与HttpURLConnection类
URLConnection与HttpURLConnection的作用
URLConnection的连接过程。
setRequestProperty方法。
getHeaderFields方法。
getInputstream和getOutputStream方法。
getHeaderField,getContentLength,getContentEncoding,getContentType等方法。
一个HTTP连接可以被多个HttpURLConnection实例对象所共享,调用HttpURLConnection的disconnect方法可以关闭底层共享网络。


编程实例:将访问www.google.com站点的HTTP请求消息的Accept-Language头分别设置成日文和中文后,然后打印出www.google.com站点返回的所有响应消息头和网页内容。


思考与实践(1)
1描述TCP,UDP数据帧格式,并比较TCP和UDP的区别。
2画图说明应用程序,Socket,网络驱动程序之间的数据传送过程与工作关系。
3自己编写出UDP网络聊天程序。
4将完善的TCP服务程序模型子程序中的Servicer类中的向客户端输出的语句:pw.println(strWord+"--->"+strEcho);
使用下面两条语句中的任何一条替换:
   pw.print(strWord+"--->"+strEcho+"\r\n");
   pw.print(strWord+"--->"+strEcho+System.getProperty("line.separator"));
客户端都接受不到服务器端的响应信息,这是为什么呢?
5修改完善的TCP服务器程序模型例子程序,让用户可以在启动运行服务器程序时,通过程序参数指定的监听端口号。并且,用户指定的端口号被保存到一个文件中,当服务器程序喜下次启动运行时,直接从文件中读取那个端口号作为监听端口号。
6查阅HTTP协议资料,编写一个简单的Web服务器。
7利用HTTP协议的Range和Content-Range消息头,URL和HTTPURLConnection类,编写一个能实现HTTP断点续传的客户端程序。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics