java网络编程(随笔)

按规模的三种分类
局域网(LAN):指在一个较小的地理范围内的各种计算机网络设备互连在一起的通信网络,可以包含一个或多个子网,通常局限在几千米的范围之类。
城域网(MAN):主要是由城域范围内的格局域网之间互连而构成的,现在很少提起这个概念。
广域网(WAN):是由相距较远的局域网或城域网互连而成,通常是除了计算机设备以外,还要涉及一些电信通讯方式。

TCP/IP分层和OSI分层
应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
应用层 传输层 网络层 物理+数据链路层

TCP/IP协议集
应用层  SMTP FTP DNS SNMP NFS HTTP TEL-NET
传输层  TCP UDP 
网际层  ICMP IGMP  
                  IP   
                         ARP RARP
网络接口层
LAN     MAN     WAN

IP地址
IP地址用于标识网络中的一个通信实体,这个通信实体可以是一台主机,也可以是一台打印机,或者是路由器的某一个端口。而在基于IP协议网络中传输的数据包,都必须使用IP地址来进行标识。
IP地址是数字型的,IP地址是一个32位(32bit)整数,但通常为了更加便于记忆,通常也把它分成48位的二进制数组成,每8位之间用圆点隔开,每个8位整数可以转换成一个0-255的十进制整数,因此我们看到的IP地址常常是如下形式:209.9.128.88.

IP与DNS
IP地址
-连接至网络的每台计算机都是唯一的
-32位数字,四个用点号分隔的数字
-包括网络ID和主机ID
-网络的类包括A,B,C和D类E
-0-126
-128-191
-192-223
-127.0.0.1
-192.168.10.179
-10.11.0.1
域名系统
-将特定IP地址映射至字符串
-映射由域名服务器系统维护

端口
端口是一个16位的整数,用于表示数据交给那个通信程序处理。因此,端口是应用程序与外界交流的出入口,它是抽象的软件结构,包括一些数据结构和I/O(基本输入/输出)缓冲区。
不同的应用程序处理不同端口上的数据,同一台机器上不能有两个程序使用同一个端口,端口号可以从065535,通常将它分为三类:
-公认端口(Well Known Ports):01023,它们紧密绑定(Binding)一些服务。
-注册端口(Registered Port):102449151.它们松散地绑定一些服务。
-动态和/或私有端口(Dynamic and/or Private Ports):4915265535,这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。

端口
用于实现程序间的通信
常用的端口
协议                               端口
Telnet协议                         23
简单邮件传输协议                    25
文件传输协议                        21
超文本传输协议                      80

InetAddress
java提供了InetAddress类来代表IP地址,InetAddress下还有2个子类:Inet4Address,Inet6Address,它们分别代表Internet Protocol version 4(IPV4) 地址和Internet Protocol version 6(IPv6)地址。
InetAddress类没有提供构造器,而是提供了如下两个静态方法来获取InetAddress实例:
-getByName(String host):根据主机获取对应的InetAddress对象。
-getByAddress(byte[]addr):根据原始IP地址来获取对应的InetAddress对象。
InetAddress还提供了如下三个方法来获取InetAddress实例对应的IP地址和主机名:
-String getCanonicalHostName():获取此IP地址的全限定域名。
-String getHostAddress():返回该InetAddress实例对应的IP地址字符串(以字符串形式)。
-String getHostName():获取此IP地址的主机名。

URLDecoder和URLEncoder
URLDecoder类包含一个decode(String s,String enc)静态方法,它可以将看上去是乱码的特殊字符串转换成普通字符串。
URLEncoder类包含一个encode(String s ,String enc)静态方法,它可以将普通字符串转换成application/x-www-form-urlencoded MIME字符串。

URL
URL(Uniform Resource Locator)对象代表统一资源定位器,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更复杂的对象引用,例如对数据库或搜索引擎的查询。通常情况而言,URL可以由协议名,主机,端口和资源组成。即满足如下格式:
protocol://host:port/resourceName

URLConnection
程序可以通过URLConnection实例向该URL发送请求,读取URL引用的资源。
通常创建一个URL的连接,并发送请求,读取此URL引用的资源需要如下几个步骤:
-1)通过调用URL对象openConnection()方法来创建URLConnection对象。
-2)设置URLConnection的参数和普通请求属性 。
-3)如果只是发送GET方式请求,使用connect方法建立和远程资源之间的实际连接即可;如果需要发送POST方式的请求,需要获取URLConnection实例对应的输出流来发送请求参数。
-4)远程资源变为可用,程序可以访问远程资源的头字段,或通过输入流读取远程资源的数据。

IP协议
IP协议是Internet上使用的一个关键协议,它的全称是Internet Protocol,即Internet协议,通常简称IP协议。通过使用IP协议,从而使Internet成为一个允许连接不同类型的计算和不同操作系统的网络
IP协议只保证计算机能发送和接收分组数据。IP协议负责将消息从一个主机传送到另一个主机,消息在传送的过程中被分割成一个个的小包。

Java对TCP/IP协议的支持
TCP/IP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路。一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信。Java对基于TCP协议的网络通信提供了良好的封装,Java使用Socket对象来代表两端的通信接口,并通过Socket产生IO流来进行网络通信。
TCP协议负责收集这些信息包,并将其按适当的次序放好传送,在接收端收到后再将其正确地还原。TCP协议保证了数据包在传送中准确无误。TCP协议使用重发机制:当一个通信实体发送一个消息给另一个通信实体后,需要收到另一个通信实体确认信息,如果没有收到另一个通信实体的确认信息,则会再次重发刚才发送的信息。
通过这种重发机制,TCP协议向应用程序提供可靠通信连接,使它能够自动适应网上的各种变化。即使在Internet暂时出现堵塞的情况下,TCP也能够保证通信的可靠。

ServerSocket
ServerSocket对象用于监听来自客户端的Socket连接,如果没有连接,它将一直处于等待状态.ServerSocket包含一个监听来自客户端连接请求的方法:
Socket accept():如果接收到一个客户端Socket的连接请求,该方法将返回一个与连接客户端Socket对应的Socket;否则该方法将一直处于等待状态,线程也被阻塞。
为了创建ServerSocket对象,ServerSocket类提供了如下几个构造器:
-ServerSocket(int port):用指定的端口Port来床创建一个ServerSocket.该端口应该是有一个有效的端口整数值:0-65535.
-ServerSockt(int port,int backlog):增加一个用来改变连接队列长度的参数backlog.
ServerSocket(int port,backlog,InetAddress localAddr):在机器存在多个IP地址的情况下,允许通过localAddr这个参数来指定将ServerSocket绑定到指定的IP地址。

Socket
客户端通常可使用Socket的构造器来连接到指定服务器,Socket通常可使用如下两个构造器:
-Socket(InetAddress/String remoteAddress,int port):创建连接到指定远程主机,远程端口的Socket,该构造器没有指定本地地址,本地端口,该构造器没有指定本地地址,本地端口,默认使用本地主机的默认IP地址,默认使用系统动态指定的IP地址。
-Socket(InetAddress/String remoteAddress,int port,InetAddress localAddr,int localPort):创建连接到指定远程主机,远程端口的Socket,并指定本地IP地址和本地端口号,适用于本地主机有多个IP地址的情形。

网络通信
当客户端,服务器端产生了对应的Socket之后,程序无需再区分服务器,客户端,而是通过各自的Socket进行通信,Socket提供如下两个方法来获取输入流和输出流:
-InputStream getInputStream():返回该Socket对象对应的输入流,让程序通过该输入流从Socket中取出数据。
-OutputStream getOutputStream():返回该Socket对象对应的输出流,让程序通过该输出流向Socket中输出数据。

客户端
通过Socket建立对象并指定要连接的服务端主机以及端口。
Socket s =new Socket("192.168.1.1",9999);
OutputStream out = s.getOutputStream();
out.write("hellow".getBytes());
s.close();

服务端
建立服务端需要监听一个端口
ServerSocket ss = new ServerSocket(9999);
Socket s  =ss.accept();
InputStream in = s.getInputStream();
byte [] buf = new byte[1024];
int num  = in.red(buf);
String str  = new String(buf,0,num);
System.out.println(s.getInetAddress().toString()+";"+str);
s.close();
ss.close();

加入多线程支持
实际应用中的客户端则可能需要和服务器保持长时间通信,即服务器需要不断地读取客户端数据,并向客户端写入数据;客户端也需要不断地读取服务器数据,并向服务器写入数据。
使用传统BufferedReader的readLine()方法读取数据时,当该方法成功返回之前,线程都被阻塞,程序无法继续执行。考虑到这个原因,因此服务器应该每个Socket单独启动一条线程,每条线程负责与一个客户端进行通信。
客户端读取服务器数据的线程同样会被阻塞,所以系统应该单独启动一条线程,该线程专门负责读取服务器数据。

NIO实现非阻塞通信
Java的INO非阻塞的Socket通信提供了如下几个特殊类:
-Selector:它是SelectableChannel对象的多路复用器,所有希望采用非阻塞方式进行通信的Channel都应该注册到Selector对象。可通过调用此类的静态open()方法来创建Selector实例,该方法将使用系统默认的Selector来返回新的Slector.
-SelectableChannel:它代表可以支持非阻塞IO操作的Channel对象,可以将其注册到Selector上,这种注册的关系由SelectionKey实例表示。Selector对象提供了一个select()方法,该方法允应用程序同时监控多个IO Channel.
-SeletionKey:该对象代表SelectableChannel和Selector之间的注册关系。
-ServerSocketChannel:支持非阻塞操作,对应于java.net.ServerSocket这个类,提供了TCP协议IO接口,支持OP_ACCEPT操作。该类也提供了accept()方法,功能相当于ServerSocket提供的accpet()方法。

-SocketChannel:支持非阻塞操作,对应Java.net.Socket这个类,提供了TCP协议IO接口,支持OP_CONNECT,OP_READ和OP_WRITE操作。这个类还实现了ByteChannel接口,ScatteringByteChannel接口和GatheringByteChannel接口,所以可以直接通过SocketChannel来读写ByteBuffer对象。

NIO的非阻塞通信
服务器上所有Channel(包括ServerSocketChannel和SocketChannel)都需要向Selector注册,而该Selector则负责监视这些Socket的IO状态,当其中任意一个或多个Channel具有可用的IO操作时,该Selector的select()方法将会返回大于0的整数,该整数值就表示该Selector上有多少个Channel具有可用的IO操作,并提供了selectedKeys()方法来返回这些Channel对应的SelectionKey集合。正是通过Selector,使得服务器端只需要不断地调用Selector实例的select()方法即可知道当前所有Channel是否有需要处理的IO操作。

UDP协议
UDP协议是一种不可靠的网络协议,它在通信实例的两端各建立一个Socket,但这两个Socket之间并没有虚拟链路,这两个Socket只是发送,接收数据包的对象,Java提供了DatagramSocket对象作为基于UDP协议的Socket,使用DatagramPacket代表DatagramSocket发送,接收的数据包。

UDP和TCP的对比
TCP协议:可靠,传输大小无限制,但是需要连接建立时间,差错控制开销大。
UDP协议:不可靠,差错控制开销小,传输大小限制在64K一下,不需要建立连接。

发送数据包
DatagramSocket本身只是码头,不维护状态,不能产生IO流,它的唯一作用就是接受和发送数据包,Java使用DatagramPacketl来代表数据报,DatagramSocket接收和发送的数据都是通过DatagramPacket对象完成的。
DatagramSocket的构造器:
-DatagramSocket():创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址,本机所有可用端口中随机选择的某个端口。
-DatagramSocket(int prot):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址,指定端口。
-DatagramSocket(int port ,InetAddress laddr):创建一个DatagramSocket实例,并将该对象绑定到指定IP地址,指定端口。

DatagramSocket实例,通常在创建服务器时,我们创建指定端口的DatagramSocet实例---这样保证其他客户端可以将数据发送到该服务器。一旦得到了DatagramSocket实例之后,就可以通过如下两个方法来接收和发送数据:
-receive(DatagramPacket p):从该DatagramSocket中接收数据报。
-send(DatagramPacket p):以该DatagramSocket对象向外发送数据报。

DatagramPacket
DatagramPacket自身决定数据报的目的。
DatagramPacket的构造器:
-DatagramPacket(byte buf[],int length):以一个空数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。
-DatagramPacket(byte buf[],int length,InetAddress addr,int port):以一个包含数据的数组来创建DatagramPacket对象,创建该DatagramPacket时还指定了IP地址和端口————这就决定了该数据的报的目的。
-DatagramPacket(byte[] buf,int offset,int length):以一个空数组来创建DatagramPacket对象,并指定接收到的数据放入buf数组中时从offset开始,最多放length个字节。
-DatagramPacket(byte[] buf,int offset,int length,InetAddress address, int port):创建一个用于发送的Datagram Packet对象,也多指定了一个offset参数。

通过DatagramPacket反馈
获取DatagramPacket对象后,如果想向该数据报的发送者“反馈”一些信息,但由于UDP是面向非连接的,所以接受者并不知道每个数据报由谁发送过来,但程序可以调用DatagramPcket的如下三个方法来获取发送者的IP和端口:
-InetAddress getAddress(): 返回某台机器的IP地址。当程序准备发送此数据报时,该方法返回此数据报的目标机器的IP地址;当程序刚刚接收到一个数据报时,该方法返回该数据报的发送主机的IP地址。
-int getPort():返回某台机器的端口,当程序准备发送此数据报时,该方法返回此数据报的目标机器的端口;当程序刚刚接收到一个数据报时,该方法返回该数据报的发送主机的端口。
-SocketAddress getSocketAddress():返回完整SocketAddress,通常由IP地址和端口组成。当程序准备发送此数据时,该方法返回此数据报的目标SocketAddress;当程序刚刚接收到一个数据报时,该方法返回该数据报源SocketAddress.

发送端
在发送端,要在数据包对象中明确目的地IP及端口。
DatagramSocket ds =new DatagramSocket();
byte[] by ="hello,udp".getBytes();
DatagramPacket dp = new DatagramPaket(by,0,by.length,Inet Address.getByName("127.0.0.1"),10000)
ds.send(dp);
ds.close();

接收端
在接收端,要指定监听的端口
DatagramSockt ds =new DatagramSocket(10000);
byte[] by = new byte[1024];
DatagramPacket dp=new DatagramPacket(by,by.length);
ds.receive(dp);
String str = new String(dp.getData());
System.out.println(str+"--"+dp.getAddress());
ds.close();

MulticastSocket与多点广播
DatagramSocket只允许数据报发送给定指定的目标地址,而MulticastSocket可以将数据报以广播方式发送到数量不等的多个客户端。
若要使用多点广播时,则需要让一个数据报标有一组目标主机地址,当数据报发出后,整个组的所有主机都能收到该数据报。IP多点广播(或多点发送)实现了将单一信息发送到多个接收者的广播,其思想是设置一组特殊网络地址作为多点,广播地址,每一个多点广播地址都被看作一组,当客户端需要发送,接收广播信息时,加入到该组即可。

MulicastSocket
MulicastSocket把一个DatagramPacket发送到多点广播IP地址后,该数据报将被自动广播给加入该地址的所有MyulticastSocket.MulticastSocket类既可以将数据报发送到多点广播地址,也可以接收其他主机的广播信息/
MulticastSocket有点像DatagramSocket,事实上MulticastSocket是DatagramSocket的一个子类,也就是说MulticastSocket是特殊的DatagramScoket.若要发送一个数据报时,可使用随机端口创建MulticastSocket,也可以在指定端口来创建MulticastSocket.MulticastSocket提供了如下三个构造器:
-public MulticastSocket():使用本默认地址,随机端口来创建一个MulticastSocket对象。
-public MulticastSocket(int portNumber):使用本机默认地址,指定端口来创建一个MulticastSocket对象。
-public  MulticastSocket(SocketAddress bindaddr):使用本机指定IP地址,指定端口来创建一个MulticastSocket对象。

加入多点广播
创建一个MulticastSocket对象后,还需要将该MulticastSocket加入到指定的多点广播地址,MulticastSocket使用joinGroup()方法来加入指定组;使用leaveGroup()方法脱离一个组。
-joinGroup(InetAddress multicastAddr):将该MulticastSocket加入指定的多点广播地址。
-leaveGroup(InetAddress multicastAddr):让该MulticastSocket离开指定的多点广播地址。

代理服务器
代理服务器的功能就是代理网络用户去取得网络信息。我们使用网络浏览器直接连接其他Intenet站点取得网络信息时,通常需要发送Request请求来等待响应。代理服务器是介于浏览器和Web服务器之间的一台服务器,有了它之后,浏览器不是直接到Web服务器去取得网页数据,而是向代理服务器发出请求,Request请求会先送到代理服务器,由代理服务器来取回浏览器所需的信息并送回给网络浏览器。

使用Proxy
Proxy有如下一个构造器:Proxy(Proxy.Type type,SocketAddress sa):创建代表服务器的Proxy对象。而sa参数指定代理服务器的地址,其中type是该代理服务器的类型,该服务器类型有如下三种:
-Proxy.Type.DIRECT:表示直接连接或代理不存在。
-Proxy.Type.Http:表示高级协议的代理,如HTTP或FTP。
-Proxy.Type.SOCKS:表示SOCKS(V4或V5)代理。
一旦创建了Proxy对象,作为本次连接所使用的代理服务器。
其中URL包含了一个URLConnectionopenConnection(Proxy proxy)方法,该方法使用指定的代理服务来打开连接;而Socket则提供了一个Socket(Proxy proxy)构造器,该构造器使用指定的代理服务器,该构造器使用指定的代理服务器创建一个没有连接的Socket对象。

使用ProxySelector
ProxySelctor可以它根据不同的连接使用不同的代理服务器。系统默认的ProxySelector会检测各种系统属性和URL协议,然后决定怎样连接不同主机。当然,程序也可以调用ProxySelector类的setDefault()静态方法来设置默认代理服务器,也可以调用getDefault()方获得系统当前默认的代理服务器。
程序可以通过System类来设置系统的代理服务器属性,关于代理服务器常用的属性名有如下三个:
-http.proxyHost:设置HTTP访问所使用的代理服务器地址。该属性名的前缀可以改为https,ftp等,分别用于设置HTTP访问,安全HTTP访问和FTP所用的代理服务器地址。
-http.proxyPort:设置HTTP访问所使用的代理服务器端口。该属性名的前缀可以改为https,ftp等,分别用以设置HTTP访问,安全HTTP访问和FTP访问所用的代理服务器端口。
-http.nonProxyHosts:设置HTTP访问中不需要使用代理服务器的远程主机,可以使用*通配符,如果有多个地址,多个地址用竖线(|)分隔。

自定义ProxySelector
系统提供了默认的ProxySelector子类作为代理选择器,开发者可以实现自己的代理选择器,程序可以通过继承ProxySelector来实现自己的代理选择器。继承ProxySelector需要重写两个方法:
-List<Proxy>select(URL uri):实现该方法让代理选择器根据不同的URI来使用不同的代理服务器,该方法就是代理选择器管理网络连接使用代理服务器的关键。
-connectFailed(URI uri,SocketAddress sa,IOException ioe):当系统通过默认的代理服务器建立连接失败后,代理选择器将会自动调用该方法。通过重写该方法可以对连接代理服务器失败的情形进行处理。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值