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 ...
随机推荐
- 初识JVM:(一)JVM工作原理和流程
本文主要参考:http://blog.csdn.net/CSDN_980979768/article/details/47281037?locationNum=7&fps=1 声明:主要用于个 ...
- vue的$message(提示框换行)
之前一直在搜怎么让提示框的文字换行,网上搜到的基本都是使用 ‘ /n ’,使用无效,也试了css换行,本来想用弹窗自己编辑html内容,还好回去官网看了一下: let arr = ['测试一', '测 ...
- ajax4
用jquery实现json jquery.ajax([settings]) type类型使用“POST”或者“GET”,默认使用get URL:发送请求地址 data:是一个对象,连同请求发送到服务器 ...
- 题解 NOI1999【生日蛋糕】—— 洛谷
自己想出这题的大佬蒟蒻在这儿%您了 我实在是太弱了,搜索这种辣鸡算法都不会(逃 这题真的是想了好久,每次都会T三个点,我以为我的剪枝已经堆了够多了,结果后来才知道是一个关键剪枝没想到OTZ 先贴代码 ...
- this.baseInfoList = [...this.baseInfoList] 所有和数组有关的操作,最后一定都展开一次,否则就没有双向绑定!!
this.baseInfoList = [...this.baseInfoList] 所有和数组有关的操作,最后一定都展开一次,否则就没有双向绑定!! this.baseInfoList = [... ...
- div或者p标签单行和多行超出显示省略号
单行文本溢出显示省略号 overflow: hidden;text-overflow:ellipsis;white-space: nowrap;多行文本显示省略号 display: -webkit-b ...
- Vysor Pro1.9.3破解,连接 USB 数据线在电脑上远程控制 Android 手机平板/同步显示画面
Vysor PRO 破解方法 1.下载Vysor Pro, Vysor Pro下载地址 ,chrome版需要挂梯子. 下载后,能连接,但是清晰度太低,能使用的功能也很少,下面我们就开始来破解它. ...
- 050.集群管理-Prometheus+Grafana监控方案
一 Prometheus概述 1.1 Prometheus简介 Prometheus是由SoundCloud公司开发的开源监控系统,是继Kubernetes之后CNCF第2个毕业的项目,在容器和微服务 ...
- PTEST 渗透测试标准
1:前期交互阶段 在前期交互(Pre-Engagement Interaction)阶段,渗透测试团队与客户组织进行交互讨论,最重要的是确定渗透测试的范围.目标.限制条件以及服务合同细节.该阶段通常涉 ...
- 渗透测试-IP相关知识整理
IP地址: 英文名称为Internet Protocol Address,是指互联网协议地址又称为网际协议地址.IP地址是Ip协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台机器分配一个 ...