Java 网络编程相关知识
网络的一些基础知识
IP地址分类
IP地址根据网络ID的不同分为5种类型,A类地址、B类地址、C类地址、D类地址和E类地址。A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同。(IP地址由网络号和主机号组成)。
A类地址
一个A类IP地址由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”, 地址范围从1.0.0.0 到126.0.0.0。可用的A类网络有126个,每个网络能容纳1亿多个主机。A类地址一般分配给大型网络。
- A类地址第1字节为网络地址,其它3个字节为主机地址,默认的子网掩码255.0.0.0。
- A类地址范围:0.0.0.0—126.255.255.255(0.0.0.0和126.255.255.255这种IP一般不使用)。
- A类地址中的私有地址和保留地址。
- 10.X.X.X是私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。
- 127.X.X.X是保留地址,用做循环测试用的。
B类地址
一个B类IP地址由2个字节的网络地址和2个字节的主机地址组成,网络地址的最高位必须是“10”,地址范围从128.0.0.0到191.255.255.255。可用的B类网络有16382个,每个网络能容纳6万多个主机,一般分配给中型网络 。
- B类地址第1字节和第2字节为网络地址,其它2个字节为主机地址,默认子网掩码是255.255.0.0。
- B类地址范围:128.0.0.0—191.255.255.255(128.0.0.0和191.255.255.255这种地址一般不用)。
- B类地址的私有地址和保留地址。
- 172.16.0.0—172.31.255.255是私有地址。
- 169.254.X.X是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会得到其中一个IP。
C类地址
一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址的最高位必须是“110”。范围从192.0.0.0到223.255.255.255。C类网络可达209万余个,每个网络能容纳254个主机。
- C类地址前3个字节为网络地址,第4个个字节为主机地址。另外第1个字节的前三位固定为110,默认子网掩码是255.255.255.0。
- C类地址范围:192.0.0.0—223.255.255.255(192.0.0.0和223.255.255.255一般不用)。
- C类地址中的私有地址。
- 192.168.X.X是私有地址。
D类地址
D类IP地址第一个字节以“1110”开始,它是一个专门保留的地址。它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中。多点广播地址用来一次寻址一组计算机,它标识共享同一协议的一组计算机。
- D类地址不分网络地址和主机地址,它的第1个字节的前四位固定为1110。
- D类地址范围:224.0.0.1—239.255.255.254。
E类地址
以“11110”开始,为将来使用保留。全零(“0.0.0.0”)地址对应于当前主机。全“1”的IP地址(“255.255.255.255”)是当前子网的广播地址。
- E类地址也不分网络地址和主机地址,它的第1个字节的前五位固定为11110。
- E类地址范围:240.0.0.1—255.255.255.254
端口分类
- 公认端口(well know port):从0到1023,他们紧密绑定一些特定服务。比如80端口绑定http服务,443端口绑定https服务,22端口绑定ssh服务等;
- 主粗端口(Registed port):1024到49151,他们松散的绑定一些服务,我们自己写的应用程序应该使用这个范围内的端口;
- 动态或私有端口:49152到65535,这些端口应用程序会动态使用。
Java的基本网络支持
Java中对网络支持的类大都在java.net这个包下面,常用的类有URL、URLConnection、URLDecoder、URLENcoder和InetAddress等。
InetAddress的使用
InetAddress代表IP地址,它有两个子类Inet4Address和Inet6Address。
public class InetAddressDemo {
public static void main(String[] args) throws Exception {
//获取本机的IP地址
InetAddress localHost = InetAddress.getLocalHost();
System.out.println("host address:"+localHost.getHostAddress());
System.out.println("host name:"+localHost.getHostName());
//根据百度的域名,随机获取百度的一个IP地址
InetAddress baidu = InetAddress.getByName("www.baidu.com");
System.out.println("host address:"+baidu.getHostAddress());
System.out.println("host name:"+baidu.getHostName());
//根据IP地址,货期InetAddress
InetAddress loopAddress = InetAddress.getByAddress(new byte[]{127,0,0,1});
System.out.println("host address:"+loopAddress.getHostAddress());
System.out.println("host name:"+loopAddress.getHostName());
//根据域名,获取域名对应的所有IP地址
InetAddress[] baidus = InetAddress.getAllByName("www.baidu.com");
for (InetAddress inetAddress : baidus) {
System.out.println("host address:"+inetAddress.getHostAddress());
System.out.println("host name:"+inetAddress.getHostName());
}
}
}
URLEncoder和URLDecoder的使用
当URL地址中包含非西欧字符的字符串时,系统会将这些非西欧字符自动编码。在我们编程过程中就会涉及到将这些普通的字符串和特殊字符串之间的转换,这时就需要使用URLEncoder和URLDecoder。
String encodedUrl = "https://www.baidu.com/s?wd=ip%E5%9C%B0%E5%9D%80%E5%88%86%E7%B1%BB&rsv_spt=1&rsv_iqid=0xe6273c5300071242&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf-8&rqlang=cn&tn=baiduhome_pg&rsv_enter=1&oq=IP%25E5%259C%25B0%25E5%259D%2580%25E5%2588%2586%25E7%25B1%25BB&rsv_t=8798Pr4JiDoBuHX8kSW6i384TlOk5p8vEQ4c4tWrc0suF31CjvBh6stq0gyq0PtETa9x&inputT=9569&rsv_sug3=24&rsv_sug1=14&rsv_sug7=100&rsv_pq=b3c08c4200035639&bs=IP%E5%9C%B0%E5%9D%80%E5%88%86%E7%B1%BB";
String decodeURL = URLDecoder.decode(encodedUrl, Charset.forName("UTF8").name());
System.out.println("decodeURL:"+decodeURL);
URLEncoder和URLDecoder这两个类只提供了encode和decode方法供我们使用。
URL、URLConnection和URLPermission的使用
这边先讲下URL和URI的区别:
URI:是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的URI一般由三部组成:①访问资源的命名机制②存放资源的主机名③资源自身的名称,由路径表示,着重强调于资源。
URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。URL一般由三部组成:①协议(或称为服务方式)②存有该资源的主机IP地址(有时也包括端口号)③主机资源的具体地址。
简单的说,URI是一种互联网上资源的唯一标识符(我们可以将它看成一个资源的id),URL是一种特殊的URI,URL不仅能标识一个互联网资源,而且通过URL能够获取到这个资源。Java中的两个类URI和URL就分别对应这两个概念。URL类可以打开一个流来获取具体的资源。
String[] urls = {"https://img0.pconline.com.cn/pconline/1707/21/9625301_20150814_6d20f056ee9803d9419buyemaASeB0KJ_thumb.jpg"};
for (String url : urls) {
URL url1 = new URL(url);
int port = url1.getPort();
System.out.println("port:"+port);
String host = url1.getHost();
System.out.println("host:"+host);
String protocol = url1.getProtocol();
System.out.println("protocol:"+protocol);
String file = url1.getFile();
System.out.println("fileName:"+file);
//这段是否要设置权限,为什么open总是失败?
InputStream inputStream = url1.openStream();
FileOutputStream fos = new FileOutputStream("D:\\"+new Date()+".jpeg");
FileCopyUtils.copy(inputStream,fos);
inputStream.close();
fos.close();
}
基于TCP协议的网络编程
使用ServerSocket建立TCP服务端
Java中能够接收其他通信实体请求的类是ServerSocket。这个对象可以监听来自客户端的Socket连接(每个TCP连接两个Socket,一个IP加一个端口组成一个Socket)。如果没有连接,它将一直处于等待状态。
- Socket accept():该方法返回客户端Socket,没有连接将一直处于等待状态(同步),线程也被阻塞(阻塞);
ServerSocket存在如下的构造函数:
- public ServerSocket(int port):指定端口,backlog默认50;
- public ServerSocket(int port, int backlog) :backlog用于指定连接队列的长度,这个值和操作系统也有关,尝试了下Windows下最多设置200个,如果我们设置的值超过200,就取200。
- public ServerSocket(int port, int backlog, InetAddress bindAddr):如果机器有多个网卡还可以指定具体监听哪个网卡。
(netstat 命令详解)
使用Socket进行通信
下面是一个很加单的clientSocket和serverSocket的列子:客户端每隔一秒钟给服务端发一个消息,服务端给出响应:
Socket clientSocket = new Socket("127.0.0.1",30000);
//inputStream用来接受服务端返回的消息
InputStream inputStream = clientSocket.getInputStream();
//outputStream用来给服务端发消息
OutputStream outputStream = clientSocket.getOutputStream();
while (true){
outputStream.write(("hi, l am clinetSocket").getBytes());
byte[] bytes = new byte[1024];
inputStream.read(bytes);
System.out.println("get message from server:"+new String(bytes));
Thread.sleep(1000);
}
服务端程序
public class ServerSocketDemo {
private static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(30000, 5);
while (true) {
Socket socket = serverSocket.accept();
System.out.println("get socket:" + socket);
executorService.execute(new Printer(socket));
}
}
private static class Printer implements Runnable {
private Socket socket;
public Printer(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
OutputStream outputStream;
InputStream inputStream;
try {
//对于服务端来说,inputStream用来接收客户端的报文
inputStream = socket.getInputStream();
//对于服务端来说,outputStream用来给客户端响应报文
outputStream = socket.getOutputStream();
while (true) {
byte[] bytes = new byte[1024];
inputStream.read(bytes);
System.out.println("wa.. l got you " + new String(bytes));
outputStream.write("l am serverSocket".getBytes());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
半关闭的Socket
半关闭的Socket是指只关闭Socket的输入输出流,但是不关闭整个Socket连接。
使用NIO实现非阻塞的Socket通信
Java NIO下几个用于Socket通信的类的简单说明:
- Selector:它是SelectableChannel对象的多路复用器器,所有希望采用非阻塞方式进行通信的Channel都应该注册到Selector对象上。可以调用selector = Selector.open()来构造Selector对象。
- SelectionKey:一个Selector实例有三种SelectionKey集合。第一种是通过selector的keys()方法返回的所有SelectionKey集合,代表所有注册在这个Selector实例上的Channel;第二种是通过selectedKeys()方法返回的SelectionKey集合,代表需要进行IO处理的channel;第三种是已经取消注册的Channel,一般不用。
public class NioServerSocketDemo {
private Selector selector;
public static final int port = 30000;
private Charset charset = Charset.forName("UTF-8");
public void init() throws Exception{
selector = Selector.open();
ServerSocketChannel server = ServerSocketChannel.open();
InetSocketAddress address = new InetSocketAddress("127.0.0.1",port);
server.bind(address,5);
server.configureBlocking(false);
//serverSocketChannel也要注册到selector上面
server.register(selector, SelectionKey.OP_ACCEPT);
//selector.select()会阻塞当前线程
//selector.select(long timeout),设置超时时间
//selector.selectNow()不会阻塞线程
while (selector.select()>0){
for(SelectionKey key : selector.selectedKeys()){
//已经处理过了,将其删除
selector.selectedKeys().remove(key);
if(key.isConnectable()){
SocketChannel channel = (SocketChannel)key.channel();
System.out.println(channel+" has connected...");
}
if(key.isAcceptable()){
SocketChannel acceptChannel = server.accept();
acceptChannel.configureBlocking(false);
acceptChannel.register(selector,SelectionKey.OP_READ);
key.interestOps(SelectionKey.OP_ACCEPT);
}
if(key.isReadable()){
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
String content = "";
try{
while (channel.read(buffer)>0){
buffer.flip();
content+=charset.decode(buffer);
}
System.out.println("get content:"+content);
channel.write(buffer);
key.interestOps(SelectionKey.OP_READ);
}catch (IOException ex){
key.cancel();
if(key.channel()!=null){
key.channel().close();
}
}
}
}
}
}
public static void main(String[] args) throws Exception {
new NioServerSocketDemo().init();
}
}
使用AIO实现非阻塞的Socket通信
public class AIOServerSocket {
private static Charset charset = Charset.forName("UTF-8");
public static void main(String[] args) throws Exception {
AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(30000),1000);
while (true){
Future<AsynchronousSocketChannel> future = serverSocketChannel.accept();
AsynchronousSocketChannel socketChannel = future.get();
ByteBuffer buffer = ByteBuffer.allocate(1024);
socketChannel.read(buffer);
System.out.println("get from client:"+charset.decode(buffer));
}
}
}
Java 网络编程相关知识的更多相关文章
- 【Java基础】Java网络编程基础知识
什么是网络编程 网络编程是通过使用套接字来达到进程间通信目的,那什么是套接字呢?其实套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的 ...
- JAVA网络编程基础知识
网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯.网络编程中有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协 ...
- java网络编程基本知识
1.基本概念 网络:一组相互连接的计算机,多台计算机组成,使用物理线路进行连接 网络连接的功能:交换数据.共享资源 网络编程3要素: IP 地址:唯一标识网络上的每一台计算机,两台计算机之间通信的必备 ...
- Python 网络编程相关知识学习
Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...
- 读书笔记——网络编程与开发技术(3)基于TCP/IP协议的网络编程相关知识
TCP/IP协议:数据链路层,网络层,传输层,应用层. IP地址分为5类:A类.B类.C类.D类.E类. (A类.B类.C类是基本类,D类多用于多播传送,E类为保留类.) "*"表 ...
- Java并发编程相关知识整理
1.什么是进程.线程.多线程? 进程当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.进程间通讯依靠IPC资源,例如管道.套接字 线程是程序中的 ...
- Java工程师学习指南第5部分:Java网络编程与NIO
本文整理了微信公众号[Java技术江湖]发表和转载过的Java网络编程相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧. 深度解读 Tomcat 中的 NIO 模型 [Java基本功]浅 ...
- Java网络编程与NIO详解10:深度解读Tomcat中的NIO模型
本文转自:http://www.sohu.com/a/203838233_827544 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 ht ...
- Java网络编程与NIO详解2:JAVA NIO 一步步构建IO多路复用的请求模型
本文转载自:https://github.com/jasonGeng88/blog 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 http ...
随机推荐
- springboot连接redis错误 io.lettuce.core.RedisCommandTimeoutException:
springboot连接redis报错 超时连接不上 可以从以下方面排查 1查看自己的配置文件信息,把超时时间不要设置0毫秒 设置5000毫秒 2redis服务长时间不连接就会休眠,也会连接不上 重 ...
- c++中比较好用的黑科技
切入正题,上黑科技 一.黑科技函数(常用的我就不写了,例如sort函数) 1.next_permutation(a+1,a+1+n) a[1-n]全排列 2.reverse(a+1,a+1+n) 将a ...
- CentOS7系统更换软件安装源
1.备份你的原镜像文件,以免出错后可以恢复. cp /etc/yum.repos.d/CentOS-Base.repo{,.backup} # 或者 mv /etc/yum.repos.d/CentO ...
- 浅谈CSRF(跨站请求伪造)攻击方式
一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSR ...
- hive实践_01
本地一份包含有中文的文本文件在上传到hive前,需要先转化为UTF-8格式,否则会出现乱码.(notepad++ 格式>>>转化UTF-8编码格式) -------------- ...
- LeetCode-使数组唯一的最小增量
题目描述: 给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1. 返回使 A 中的每个值都是唯一的最少操作次数. 示例: 输入:[1,2,2] 输出:1 解释:经过一次 mo ...
- C++ 人脸识别系统的浅理解
机器学习 机器学习的目的是把数据转换成信息. 机器学习通过从数据里提取规则或模式来把数据转成信息. 人脸识别 人脸识别通过级联分类器对特征的分级筛选来确定是否是人脸. 每个节点的正确识别率很高,但正确 ...
- Arch Linux安装配置-双系统(1)
Arch Linux启动盘准备: 在Windows下安装Win32 Disk Imager,打开页面,点击Download即可! 安装配置 1.选择我同意 2.选择安装位置路径 3.打勾,在桌面显示图 ...
- AI学习笔记:人工智能与机器学习概述
一.人工智能基本概念 1.1 基本概念 数据分析:对历史规律的展现.对未来数据的预测. 机器学习:机器学习是指从一系列的原始数据中找到规律,提取人们可以识别的特征,然后通过学习这些特征,最终产生一个模 ...
- hibernate连接oracle
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-configuration PUBLIC & ...