公司有计划打算做消息推送,自己也是闲着没事稍微了解一下,从基础开始学习以便真正使用的时候不用太过紧张吧。消息推送在各种应用非常的常见,这是网络编程的一种,还是从根本上开始了解吧。
一、IP和端口号
网络中的计算机能够进行通信,必须为每台计算机指定一个标识号,通过这个标识号来指定接收数据的计算机或者发送数据的计算机。这个标识号就是IP地址,唯一标识计算机,IP地址现在广泛使用版本是IPv4。一张图说明IP地址和端口号的作用。
二、InteAddress
JDK中提供一个类InteAddress,该类封装了IP地址,提供与IP地址相关的方法。
方法声明 |
功能描述 |
InetAddress getByName(String host) |
参数host代表指定主机,给定主机的主机名,确定主机IP |
InetAddress getLocalhost() |
创建一个本地主机的InetAddress对象 |
String getHostName() |
得到IP地址对于的主机名,若是本机则是计算机名,不是则是域名,没有域名则是IP地址 |
boolean isReachable(int timeout) |
判断指定时间内地址能否到达 |
String getHostAddress() |
得到字符串格式的IP地址 |
用demo说明上述方法
package test;运行显示:
import java.net.InetAddress;
public class InetAddressDemo
{
/**
* @Title: main
* @Description: InetAddress的常用方法
* @author 贾文静
* @param args
* @throws Exception
* @throws
* @date:2017-5-16.上午9:04:36
*/
public static void main(String[] args) throws Exception
{
// 创建表示本机的InetAddress对象
InetAddress localAddress = InetAddress.getLocalHost();
// 在给定主机名的前提下创建InetAddress对象
InetAddress remoteAddress = InetAddress.getByName("www.baidu.com");
// 获取PC的ip地址
System.out.println("本机的IP地址:" + localAddress.getHostAddress());
// 根据主机名创建的InetAddress获取IP地址
System.out.println("baidu的IP地址:" + remoteAddress.getHostAddress());
// 判断本机在指定时间中能否到底目标主机,demo演示3秒钟本机能否到百度的地址
System.out.println("3秒是否可达:" + remoteAddress.isReachable(3000));
// 得到IP地址的主机名
System.out.println("baidu的主机名:" + remoteAddress.getHostName());
// 获取本地的主机名
System.out.println("本机的主机名:" + localAddress.getHostName());
}
}
三、通信
通信协议有两种UDP和TCP,从简单的程度来说UDP发送端和接收端不需要建立逻辑连接,一次发送就可以解决。而TCP需要“三次握手”才能完成。所以这两种方式的通信过程是不同的。
1、UDP
发送过程需要两个类DatagramPacket和DatagramSocket。
DatagramPacket类似于物流中心两个站点发送的货物,发送的货物一般都在装载到集装箱中。而UDP中发送和接收的数据也需要一个集装箱进行打包,DatagramPacket就承担了这项任务,对数据进行装载。有了集装箱还有需要有站点来接收货物,DatagramSocket就类似于站点接收“集装箱”。
接收端
package test;展示一下什么叫做进入堵塞状态,就是在发送端还没有传递数据的时候即发送端没有运行的时候:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class DatagramPacketServer
{
/**
* @Title: main
* @Description: UDP接收端Demo
* @author 贾文静
* @param args
* @throws Exception
* @throws
* @date:2017-5-16.上午9:51:30
*/
public static void main(String[] args) throws Exception
{
// 用于存放接收的数据
byte[] buf = new byte[1024];
// DatagramSocket类似于码头,接收DatagramPacket的数据包
// 定义一个datagramsocket对象,端口号为8954
DatagramSocket ds = new DatagramSocket(8954);
// DatagramPacket类似于集装箱,封箱发送端和接收端的数据
// 指定了封装数据字节数组和数据的大小
DatagramPacket dp = new DatagramPacket(buf, 1024);
System.out.println("等待接收数据");
// 接收发送端的数据,如果没有则进入堵塞状态
ds.receive(dp);
// 获取发送数据的具体内容,长度,获取发送的IP地址字符串格式的ip地址,以及端口号
String str = new String(dp.getData(), 0, dp.getLength()) + "from"
+ dp.getAddress().getHostAddress() + ":" + dp.getPort();
// 打印获取到的内容
System.out.println(str);
// 释放资源
ds.close();
}
}
发送端:
package test;此时运行发送端之后再看接收端的显示内容。
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @ClassName: DatagramPacketClient
* @Description: 发送端展示
* @author 贾文静
* @date 2017-5-16 上午9:52:02
*
*/
public class DatagramPacketClient
{
public static void main(String[] args) throws Exception
{
// 创建一个datagramsocket对象,指定端口为3000,如果不指定,在运行期间端口随意分配
DatagramSocket ds = new DatagramSocket(3000);
// 要发送的数据
String str = "hello world";
// 创建一个要发送的数据包,包括发送数据,数据长度,接收端ip地址以及端口号
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(),
InetAddress.getByName("jiawenjing"), 8954);
System.out.println("发送信息");
// 发送数据
ds.send(dp);
// 释放资源
ds.close();
}
}
2、TCP
TCP和UDP一样都是两台计算机之间的通信,通信端都需要创建Socket对象,区别在于UDP只需要发送端和接收端,不区分客户端和服务端,计算机之间可以任意发送数据。而TCP通信严格区分客户端和服务端,必须由客户端首先去连接服务端才能实现通信。服务端不能主动连接客户端,而且服务端程序需要事先启动,等待客户端连接。
JDK中提供Socket类表示客户端,ServerSocket表示服务端。首先创建一个ServerSocket对象,相当于开启一个线程,等待客户端连接。客户端创建一个Socket对象发送请求连接。
服务端:
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer
{
public static void main(String[] args) throws Exception
{
// 创建TCPServer对象,调用listen()方法
new TcpServer().listen();
}
// 创建一个通信端口
private static final int PORT = 7788;
public void listen() throws Exception
{
// 创建ServerSocket对象,并且指定了端口号
ServerSocket serverSocket = new ServerSocket(PORT);
// 调用ServerSocket对象的accept()方法接收数据
Socket client = serverSocket.accept();
// 获取客户端的输出流
OutputStream os = client.getOutputStream();
System.out.println("开始与客户端交换数据");
//输出到客户端
os.write(("欢迎你来访").getBytes());
// 模拟执行其他功能占用的时间
Thread.sleep(5000);
System.out.println("结束与客户端交互数据");
os.close();
client.close();
}
}
客户端:
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
public class TcpSocket
{
public static void main(String[] args) throws Exception
{
// 创建TCPSocket连接,客户端去连接数据
new TcpSocket().connect();
}
// 创建通信端口与要连接的服务端一致
private static final int PORT = 7788;
public void connect() throws Exception
{
// 创建Socket对象,连接到给出地址以及端口号
Socket client = new Socket(InetAddress.getLocalHost(), PORT);
// 得到接收数据的流
InputStream is = client.getInputStream();
// 定义1024个字节数组的缓冲区
byte[] buf = new byte[1024];
// 将数据读到缓冲区中
int len = is.read(buf);
// 将缓冲区中的数据输出
System.out.println(new String(buf, 0, len));
// 关闭socket对象,释放资源
client.close();
}
}
总结
IP和端口是网络编程开始的前提,对常用方法个人认为必须有个很好的认知。网络编程涉及到UDP和TCP通信的几个类,还有相关的方法具体还需要多多练习使用。