java高薪之路__009_网络
1. InetAddress类
2. Socket: IP地址和端口号的结合,socket允许程序把网络连接当成一个流,数据在两个socket间通过IO传输, 通信的两端都要有socket. 主动发起通信请求的是客户端,等待通信请求的是服务端
3. DatagramSocket 和 DatagramPacket实现了UDP协议网络程序, 使用DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达
DatagramPacket对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号,给出了完整的地址信息,因此无须建立发送方和接收方的连接
4. URL类
URL u = new URL("http://www.baidu.com");
InputStream in = u.openStream(); URLConnection uc = u.openConnection();
uc.getInputStream();
uc.getOutputSteam();
package learn.JavaBasics.Class; import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException; public class SocketDemo {
public void server() {
ServerSocket ss = null;
Socket s = null;
InputStream in = null;
OutputStream out = null; try {
//开始在端口监听
ss = new ServerSocket(9999); //当有连接进来时,会新建一个socket
s = ss.accept(); //获取输入流
in = s.getInputStream(); //对输入流进行处理
byte[] b = new byte[1024];
int len;
String msg = ""; while((len=in.read(b)) != -1) {
msg = new String(b, 0, len);
} System.out.println("The message from "+ s.getInetAddress().getHostName()+
"(ip:"+ s.getInetAddress().getHostAddress()+") is: \""+msg+"\""); //获取输出流,反馈信息
out = s.getOutputStream();
out.write("The msg from client has been received".getBytes());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if (s != null) {
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if (ss != null) {
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if (out != null) {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} public void client() {
Socket s = null;
OutputStream out = null;
InputStream in = null; try {
//新建一个Socket
s = new Socket(InetAddress.getLocalHost(), 9999); //获取输出流
out = s.getOutputStream(); //发送信息, 并提示
out.write("This is client".getBytes());
System.out.println("client message has sent"); //这句话存在的原因是,Server端的getInputSream流的read方法是阻塞, 它在接收信息,但不知道信息是否接收完全,所以一直在等待,
//所以Server端的反馈信息无发发送过来,程序死掉,
//这里显式的通知Server,发送结束
//FileInputSteam里的read方法与这个一样,但BufferInputSteam里的read方法是非阻塞的
s.shutdownOutput(); //获取输入流,接收服务端的反馈信息
in = s.getInputStream(); byte[] b = new byte[1024];
int len;
String msg = ""; while((len=in.read(b)) != -1) {
msg = new String(b, 0, len);
}
System.out.println("Response from Server: "+msg);
System.out.println("connection over"); //这里的后边没有了,所以服务端可以不显式的提示,不影响功能
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (s != null) {
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} if (in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
new SocketDemo().server();
}
}).start(); new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
new SocketDemo().client();
}
}).start();
} }
package learn.JavaBasics.Class; import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException; public class TestUDP {
public void receive(){
DatagramSocket ds = null; try {
//定义接收的数据报大小
byte[] b = new byte[1024];
DatagramPacket packet = new DatagramPacket(b, 0, b.length); //定义一个接收的Socket,用于在特定的端口接收指定大小的数据报
ds = new DatagramSocket(9999);
ds.receive(packet); String str = new String(packet.getData(), 0, packet.getLength()); System.out.println(str);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
} public void send() {
DatagramSocket ds = null; try {
//新建一个用于发送的Socket
ds = new DatagramSocket(); //数据
byte[] b = "你好, 这里是发送端的数据, UDP sender".getBytes(); //封装数据到数据报中, 一个数据报不能大于64K, 记录着数据信息, 两端的IP和端口号
DatagramPacket packet = new DatagramPacket(b, 0, b.length, InetAddress.getLocalHost(), 9999); //使用Socket把数据报发走
ds.send(packet);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
} public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
new TestUDP().receive();
}
}).start(); new Thread(new Runnable(){
@Override
public void run() {
new TestUDP().send();
}
}).start();
}
}
要使两台设备之间能进行通信,最简单的方式就是两台机器使用线路互联。
但如果设备很多的时候会有n(n-1)/2条线路,十分不方便搭建和维护。 所以此时人们想出了一个叫网络的概念, 在这个网络中实现路由的处理和数据的交换, 这样一台设备只需要一条线路连接到网络即可。
而根据数据交换的方式不同,数据的交换可以分为:电路交换,报文交换和分组交换3种。
电路交换:线路连接 -- 通信 -- 线路断开 (电话网络)
线路独享,连接断开时才释放线路。 而此时可能存在多个交换线路共同使用同一条线路的情况, 此时人们使用了一种叫做复用的技术。
频分多路复用(FDM): 不同的频率可以在相同的链路上同时传播(真神奇,怎么同时传的,同一种物质怎么带有两种震动,还是其他方式),典型的是电视网络
时分多路复用(TDM): 分为不同的时间段
波分多路复用 (WDM) : 就是光的频分复用
码分多路复用(CDM): 广泛用于无线链路, 每个用户分配一个唯一的m bit码片序列 .... 较复杂,没研究
报文交换:---- 存储/转发
将全部的数据封装成一个报文,然后一个节点,一个节点的发送到目的主机
分组交换:---- 存储/转发
将全部的数据拆分成一系列相对较小的数据包,要给小的数据包加上一个”头“,组成一个分组。 需要在源主机和目的主机上进行报文的拆分和重组。
总的发送时间: t= dproc + dqueue + dtrans + dprop
dproc(节点处理延迟): 一个分组到达时,路由检查这个分组所携带的信息,并做相应的处理。
dqueue(排队延迟): 分组排队的时间。
dtrans(传输延迟): 节点处理一个分组发送的时间,好比收费站放行一台车需要的时间:t= M/R + nL/R。
M: 总报文大小; R: 每个节点间相同的传输速率; n: 中间的路由数(跳步数-1); L: 分组大小;
dprop(传播延迟): 分组在链路上传播的延迟,好比汽车在公路上的时间。
丢包: 如果路由器的缓存区已经满了,还有很多的分组过来,那再过来的分组就会被路由器忽略,即丢包。(电路交换和报文交换,不会出现丢包)
网络体系结构
网络里包含的东西这么多,这么复杂, 怎么较好的区分网络里面的细节呢? 人们想到了一种叫分层结构的东东 这里的分层是从功能上区分的,而不是从硬件上区分的。 同时分层只关注功能,而不关注它的实现,不关心是用硬件实现的,还是用软件实现的。 分层是抽象的,每一层包含这一层的硬件和协议。 分层是模块化的,只要对上下层的接口不变,内部实现不管。 实体:任何可发送或接收信息的硬件或软件进程。 在通信中,主机要完成全部的层, 而中间系统只需要完成3层,有的是两层 ---- 网络层,数据链路层和物理层 0. 物理介质
1. 物理层:规范如何在不同的介质上发送比特流,并最终产生一个统一的接口。
---- 接口特性: 机械特性、电气特性、功能特性和规程特性。
---- 比特编码: 用什么表示比特,怎么表示。
---- 数据率
---- 比特同步
---- 传输模式: 单工, 半双工, 双工。
2. 数据链路层:负责节点-节点的数据传输
---- 组帧
---- 物理寻址
---- 流量控制: 两端的发收速度统一
---- 差错控制
---- 访问控制(接入控制)
3. 网络层:负责源主机到目的主机数据分组的交付
---- 逻辑寻址(唯一的逻辑地址,如:IP地址)
---- 路由
---- 分组转发
4. 传输层:实现端对端的进程间的完整报文的传送
---- 报文的分段与重组
---- SAP寻址 (确保完整的报文提交给正确的进程,如端口号)
(x, y 就是端口号)
---- 连接控制
---- 流量控制
---- 差错控制 (链路层的差错控制可能有中间系统,而这个是针对源主机和目的主机的)
5. 应用层: 每层之间都要加“头”, 加控制信息是因为什么:(以下是可选的)
1. 要加地址信息
2. 要进行差错检测编码,保证数据正确
3. 加协议控制
网络就是硬件和数据协议的总合
硬件 ---- 完成路由的确定和数据的交换
网关:
协议
UDP: -- 复用/分用
-- 简单的错误校验
-- udp段(segment)可能丢失,并且是非按序到达
-- 无连接的, 发送方和接收方之间不需要握手, 每个udp段的处理独立于其他段
有了TCP, UDP为什么存在
-- 无须建立连接,减少延迟
-- 实现简单,无须维护连接状态
-- 头部开销小
-- 没有拥塞控制,应用可更好地控制发送时间和速率
用途
-- 流媒体(容忍丢失,速率敏感)
-- DNS, SNMP
也可完成可靠的数据传输
-- 在应用层真假可靠性机制
-- 应用特定的错误恢复机制
TCP
java高薪之路__009_网络的更多相关文章
- java高薪之路__008_Annotation
元注解 共有4种 @Retention 表示需要在什么级别保存该注释信息(生命周期) |--- RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉 |--- Reten ...
- java高薪之路__007_反射
参考地址: 1. http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html2. http://www.cnblogs.com/ ...
- java高薪之路__005_IO流
参考地址: 1. http://blog.csdn.net/yczz/article/details/38761237 File类 ObjectInputStream && Objec ...
- java高薪之路__003_集合
Java集合可分为Collection和Map两大体系 Collection接口 |---- Set: 元素无序.不可重复 |---- List: 元素有序.可重复 (动态数组) |---- Queu ...
- java高薪之路__002_异常处理
自定义异常 package learn.JavaBasics.Class; import java.util.Date; /** * 如何自定义一个异常类 * 1. 继承一个现有的异常类 * 2. 提 ...
- java高薪之路__001_类
Java中内部类分四种:成员内部类.局部内部类.静态内部类和匿名内部类.要注意静态内部类的调用方式与其他不同,采用的是类似调用类中的静态属性.静态方法的方式 Multi Level 调用不同类中的相同 ...
- java高薪之路__010_设计模式
设计模式只是一个在构建大型工程时,为了方便更改,添加,查询和管理的一种代码工具,没有必要单独为了设计模式而使用设计模式,使简单的事情复杂化. 总体来说设计模式分为三大类: 1. 创建型模式,共五种 - ...
- java高薪之路__006_多线程
线程的创建有两种方式 package learn.JavaBasics.Class; public class ThreadDemo extends Thread { private static i ...
- java高薪之路__004_泛型
参考地址: 1. http://www.cnblogs.com/lwbqqyumidi/p/3837629.html2. http://www.cnblogs.com/abcwt112/p/47350 ...
随机推荐
- Android 更新sdk
http://blog.csdn.net/xiao_ping_ping/article/details/45621663 不FQ意味着不能直接到android官网下载android SDK,但是国内有 ...
- iOS图片压缩处理
理解概念 首先,我们必须明确图片的压缩其实是两个概念: “压” 是指文件体积变小,但是像素数不变,长宽尺寸不变,那么质量可能下降. “缩” 是指文件的尺寸变小,也就是像素数减少,而长宽尺寸变小,文件体 ...
- js鲸鱼
<!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- windows下的socket网络编程(入门级)
windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...
- http://www.blogjava.net/xylz/archive/2013/08/05/402405.html
http://www.blogjava.net/xylz/archive/2013/08/05/402405.html
- android 自定义控件
学习参考:http://blog.csdn.net/hudashi/article/details/50913257 http://blog.csdn.net/gebitan505/article/d ...
- lua 模块功能
lua5.1 模块理解 http://www.lua.org/manual/5.1/manual.html#pdf-module 模块 5.3 – Modules The package librar ...
- 简要介绍Apache、php、mysql安装和工具介绍
1 安装Apache 网站:www.Apache.org下载相应的Apache,目前下载了近期的:httpd-2.2.15-win32-x86-openssl-0.9.8msi 安装简要步骤如下图: ...
- IOS密码加密
一般使用两种加密技术 1.MD5 2.以前是SHA1加密 现在流行是SHA-2加密
- 获取手机通讯录--ios
- (void)test { //这个变量用于记录授权是否成功,即用户是否允许我们访问通讯录 int __block tip=0; //声明一个通讯簿的引用 ABAdd ...