1.网络分层:OSI 七层模型 和 TCP/IP四层模型应用最为广泛
数据传输过程如下:
2.套接字:源IP和目的IP以及源端口号和目的端口号的组合成为套接字,可以唯一的确定是哪台计算机的哪个进程发出数据,流向哪里.
3.网络编程:通过使用套接字来达到进程间相互通信
4.在网络编程中,基本上所有的API都在:java.net包里
5.网络编程三要素:
1.):IP地址:
IP版本: IPV4:192.168.10.1 这种格式 只有2^32个,是有限的从2015年后开始弃用
IPV6:1080:0:0:0:800:200C:417A 有2^128个,绝壁够用的不行了
IP地址编址方案:将IP地址空间划分为A 、B 、C 、D 、E 五类,其中ABC是基本类,DE类作为多播和保留使用
A类 10.0.0.0-10.255.255.255
B类 172.16.0.0-172.31.255.255
C类 192.168.0.0-192.168.255.255
在Java中,使用InetAddress类来表示IP地址,InetAddress里面有很多静态方法,具体的可以参见JDK API 这里贴个小DEMO:
public class InetDemo {
public static void main(String[] args) throws Exception {
InetAddress ip = InetAddress.getByName("www.baidu.com");//通过主机名或域名获取IP详细信息
System.out.println(ip);//获取到的数据:www.baidu.com/183.232.231.172
System.out.println(ip.getHostName());//获取主机名或域名:www.baidu.com
System.out.println(ip.getHostAddress());//获取Ip地址:183.232.231.172
System.out.println(ip.isReachable(1000));//测试域名在指定时间内是否可达:true
}
}
2.):端口:是英文Port的意译,分为物理端口和虚拟端口,比如80端口.如果把IP比作一间房子,端口就是出入这间房子的门,一个IP地址可以有2^16-1=65536个端口,范围是0~65535,只能是整数. 同一台电脑中的端口不能重复,否则会报错.
3.):协议:常见的有HTTP、SSH、STMP、POP3、FTP等,是规定好的一种传输协议,是一种规范.
6.URI和URL
URI:统一资源标识符,是一个用于表示某一互联网资源名称的字符串,包含:主机名,标识符,相对URI.eg:http://java.sun.com:80/j2se/1.3/hello.html
URL:统一资源定位符,是对可以从互联网上得到的资源的位置和访问方法的一种简洁表示,是互联网上标准资源的地址.互联网上每一个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它.
区别:URI不能打开或操作该文件,只能看看,但URL可以打开到达该资源的输入流.
相似:URI和URL都表示一个资源路径
可以通过UrlConnection对象来读取或写入Url中的资源.
7.网络编程的编码和解码:
URLEncoder.encoder()/URLDecoder.decoder()编码和解码,值得注意的是编码和解码所用的方式必须一致,否则会乱码,另外注意IE的编码方式与众不同,请看下图:
8.传输层的协议:TCP 和 UDP
区别:
TCP:面向连接(经历三次握手),传输可靠(保证正确和数据顺序),用于传输大量数据(流模式),速度慢,建立连接需要的开销较多(时间,系统资源)
UDP:面向非连接,传输不可靠(可能会丢包),用于传输少量数据(数据包模式),速度快.
Tomcat服务器其实就是基于Tcp协议写的,这里贴个极简版的tomcat服务器:
public static void main(String[] args) throws Exception {
//1.创建服务端和客户端
ServerSocket server = new ServerSocket(2018);//端口号:2018,可以在浏览器输入:http://localhost:2018即可访问到存放在D盘下的hi.html页面
//2.服务端接收请求并返回
while(true) {
Socket client = server.accept();
System.out.println("服务端被访问");
PrintStream ps = new PrintStream(client.getOutputStream());
Scanner sc = new Scanner((new FileInputStream("D:/hi.html")));
while(sc.hasNext()) {
ps.println(sc.nextLine());
}
}
}
}
模拟UDP发送数据的也贴一个DEMO:
//UDP发送端
public class Sender {
public static void main(String[] args) throws Exception {
String sendMsg = "我想暴富";
DatagramSocket sender = new DatagramSocket(10086);
DatagramPacket p = new DatagramPacket(sendMsg.getBytes(),//发送的消息内容
sendMsg.getBytes().length,//发送消息的长度
InetAddress.getLocalHost(),//发送至哪个IP
10010);//发送至哪个软件端端口
sender.send(p);
System.out.println("消息已发送...");
sender.close();
}
}
//udp接收端
public class Reciver {
public static void main(String[] args) throws Exception {
DatagramSocket receiver = new DatagramSocket(10010);
byte[] buf = new byte[1024];
DatagramPacket p = new DatagramPacket(buf,1024);
receiver.receive(p);
String msg = new String(p.getData(),0,p.getLength());
System.out.println("消息已收到,消息内容为:"+msg);
System.out.println("发送者的Ip:"+p.getAddress()+"发送者的端口号:"+p.getPort());
receiver.close();
}
}
启动时要先启动接收端,启动后再启动发送端,这个时候可以切换控制台看到发送端发送消息和接收端接收消息.
值得注意的是,如果接收端和发送端的端口一致的话会报下面这个错误,在开发中也会经常碰到,就是端口冲突的错误: