提示:学习Java网络编程之前最好先了解计算机网络相关知识概念,例如IP、UDP、TCP等。
1.InetAddress类简介
InetAddress类主要用来代表IP地址的对象。同时InetAddress还是Inet4Address和Inet6Address两个类的父类。
InetAddress类具体实例
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressTest {
public static void main(String[] args) throws UnknownHostException {
InetAddress addrs = null;
addrs = InetAddress.getLocalHost();
System.out.println(addrs);
System.out.println(addrs.getHostName());
System.out.println(addrs.getHostAddress());
System.out.println(addrs.getCanonicalHostName());//获得远程主机域名
addrs = InetAddress.getByName("www.baidu.com");
System.out.println(addrs);
System.out.println(addrs.getHostName());
System.out.println(addrs.getHostAddress());
System.out.println(addrs.getCanonicalHostName());
InetAddress[] addrss = new InetAddress[InetAddress.getAllByNam("www.csdn.net").length];
addrss = InetAddress.getAllByName("www.csdn.net");//获取csdn网站所有IP地址
for(InetAddress x: addrss) {
System.out.println(x);
}
}
}
2.基于TCP/IP的编程接口Socket
Socket(套接字)类是基于TCP协议的编程接口,因此在使用时需要先建立连接。Socket的使用由两部分构成即客户端以及服务器端。
Socket提供的构造器和方法
方法名 | 解释 | 方法名 | 解释 |
---|---|---|---|
Socket(String address, int port) | 制定地址和端口创建套接字 | InputStream getInputStream() | 获取当前连接的输入流数据 |
Socket() | 以系统默认方式创建未连接的套接字 | OutputStream getOutStream() | 获取当前连接的输出流数据 |
close() | 关闭连接 | int getPort() | 获得当前端口号 |
InetAddress getInetAddress() | 获取当前连接的IP地址 | setSoTimeout(int timeout) | 设置连接超时时间 |
ServerSocket(int port) | 创建服务端对象,并且指出端口号 | close() | 关闭服务器连接 |
Socket accept() | 监控用户端连接并且接受此连接 | setSoTimeout(int timeout) | 设置服务器连接超时时间 |
Socket应用实例
客服端的编程步骤:创建Socket对象并且请求连接指定的服务器,使用Socket提供的方法,利用数据流技术发送对服务器的请求信息、并提取服务器发送回来的数据
具体实例
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ClientConnection {
private Socket client = null;
private InputStream input = null;
private OutputStream output = null;
private PrintWriter toServer = null;
private Scanner sc = null, data = null;
public ClientConnection() throws UnknownHostException, IOException {
client = new Socket("localhost", 1800);
input = client.getInputStream();
output = client.getOutputStream();
toServer = new PrintWriter(output, true);
sc = new Scanner(System.in);//键盘输入信息
data = new Scanner(input);
System.out.println(data.nextLine());//获取服务器第一行输入信息
while(sc.hasNextLine()) {
String line = sc.nextLine();
toServer.println(line);//将键盘输入信息发送至服务器
String fromServer = data.nextLine();
System.out.println(fromServer);//获得服务器回答
if(fromServer.equalsIgnoreCase("Bye")) {
System.out.println("Now is disconnected...");
break;
}
}
client.close();
}
public static void main(String[] args) throws UnknownHostException, IOException {
ClientConnection client= new ClientConnection();
}
}
服务器端编程步骤:创建SeverSocket对象监听指定端口,同意端口连接请求。利用数据六技术发送对客户端的相应
具体实例
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class SocketTest {
private ServerSocket server = null;
private InputStream input = null;
private OutputStream output = null;
private PrintWriter toClient = null;
private Scanner data = null;
public SocketTest() throws IOException {
System.out.println("The server is running...");
server = new ServerSocket(1800);
Socket fromClient = server.accept();
input = fromClient.getInputStream();
output = fromClient.getOutputStream();
toClient = new PrintWriter(output, true);
toClient.println("Type of quit to STOP...");
data = new Scanner(input);
while(data.hasNextLine()) {
String line = data.nextLine();
if(line.equalsIgnoreCase("quit")) {
server.close();
toClient.println("Bye");
break;
}
toClient.println(line.toUpperCase());//响应客户将客户端数据转换成大写
}
input.close();
}
public static void main(String[] args) throws IOException {
SocketTest test = new SocketTest();
}
}
也可以将客户端的localhost换成连接在互联网上的一个IP地址,这样便可以进行远程通信。也可以不编写客户端程序,启用远程登陆协议telnet,进行远程通信
3.基于UDP的编程接口Datagram
Datagram数据报式数据传输技术,基于UDP传输协议,进行用户-服务器间的数据传递。Java提供了DatagramSocket和DatagramPacket进行程序设计,调用适当的方法,实现用户-服务器编程。其中DatagramSocket用来创建端口间的通讯,DatagramPacket用来获取通过网络地址和端口以邮包方式发送来的信息。
DatagramSocket和DatagramPacket的常用构造器和方法
方法名 | 解释 | 方法名 | 解释 |
---|---|---|---|
DatagramSocket(int port, InetAddress address) | 制定端口和地址创建对象 | close() | 关闭连接 |
connect(InetAddress address, int port) | 连接指定IP地址和端口地址 | InetAddress getInetaddress() | 获取当前连接IP地址 |
disconnect() | 断开当前连接 | int getLocalPort() | 获取本地端口号 |
int getPort() | 获取当前连接端口号 | receive(DatagramPacket packet) | 获取当前连接数据报 |
send(DatagramePacket packet) | 发送当前数据报 | DatagramePacket(byte[] buf, int length) | 创建接收数据报对象 |
InetAddress getAddress() | 获取当前连接的IP地址 | byte[] getData() | 获取当前发送或者接收的数据缓冲数组 |
int getLength() | 获取当前发送或者接受的数据报长度 | int getPort() | 获取当前发送或者接受的数据报长度 |
服务器端具体实例
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class DataServerTest {
public static void main(String[] args) throws IOException {
System.out.println("Welcome! The server is running...");
String line = "Datagram packet from server: SERVER";
String promptStr = line.toUpperCase() + " Enter quit to STOP";
DatagramSocket socket = new DatagramSocket(2000);
DatagramPacket receiverPacket = null;
byte[] buf = new byte[256];
receiverPacket = new DatagramPacket(buf, buf.length);
socket.receive(receiverPacket);
buf = promptStr.getBytes();
InetAddress address = receiverPacket.getAddress();
int port = receiverPacket.getPort();
sending(socket, buf, buf.length, address, port);
while(true) {
buf = new byte[256];
receiverPacket = new DatagramPacket(buf, buf.length);
socket.receive(receiverPacket);
String receive = new String(receiverPacket.getData());
buf = receive.toUpperCase().getBytes();
sending(socket, buf, buf.length, address, port);
buf = new byte[256];
String wordCount = "(Converting from server and packet length:" + receive.trim().length() + ")";
receiverPacket = new DatagramPacket(buf, buf.length);
socket.receive(receiverPacket);
buf = wordCount.getBytes();
sending(socket, buf, buf.length, address, port);
}
}
public static void sending(DatagramSocket socket, byte[] buf, int length, InetAddress address, int port) {
DatagramPacket sendPacket = new DatagramPacket(buf, length, address, port);
try {
socket.send(sendPacket);
} catch(IOException e) {
e.printStackTrace();
}
}
}
客户端具体实例
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
public class DatagramClientTest {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
byte[] buf = new byte[256];
InetAddress address = InetAddress.getByName("localhost");
sending(socket, buf, buf.length, address, 2000);
String received = receiving(socket, buf, buf.length);
System.out.println(received);
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()) {
String line = sc.nextLine();
if(!line.trim().equals("quit")) {
buf = new byte[256];
buf = line.getBytes();
sending(socket, buf, buf.length, address, 2000);
received = receiving(socket, buf, buf.length);
buf = new byte[256];
sending(socket, buf, buf.length, address, 2000);
received = receiving(socket, buf, buf.length);
System.out.println(received);
} else {
break;
}
}
socket.close();
}
public static void sending(DatagramSocket socket, byte[] buf, int length, InetAddress address, int port) {
DatagramPacket sendPacket = new DatagramPacket(buf, length, address, port);
try {
socket.send(sendPacket);
} catch(IOException e) {
e.printStackTrace();
}
}
public static String receiving(DatagramSocket socket, byte[] buf, int length) throws IOException {
DatagramPacket receivePacket = new DatagramPacket(buf, length);
String received = null;
socket.receive(receivePacket);
received = new String(receivePacket.getData(), 0, receivePacket.getLength());
return received;
}
}
4.URL和HttpURLConnection编程
URL:统一资源定位符缩写
URL组成部分:协议类型、主机名或IP地址、端口号、路径名
常用URL类方法实例
import java.net.MalformedURLException;
import java.net.URL;
public class URLTest {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("https://www.csdn.net/");
System.out.println(url.getProtocol());
System.out.println(url.getFile());
System.out.println(url.getPath());
System.out.println(url.getHost());
System.out.println(url.getPort());
System.out.println(url.toExternalForm());//获取URL对象的字符串表现形式
}
}
常用URLConnection类方法实例
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
public class URLTest {
public static void main(String[] args) throws IOException {
URL url = new URL("https://www.csdn.net/");
URLConnection con = url.openConnection();
System.out.println(con.getContentLength());//获取该URL资源的大小
System.out.println(con.getHeaderField(1));//获取URL资源的第n个头字段的值
System.out.println(con.getContentType());//URL类型
System.out.println(con.getExpiration());//获取URL资源的期满日期
}
}
HTTPURLConnection实例爬取网页html信息
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpURLConnectionTest {
public static void main(String[] args) throws IOException {
URL http = new URL("https://www.csdn.net/");
HttpURLConnection httpCon = (HttpURLConnection) http.openConnection();
InputStream input = httpCon.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(input));
String line = br.readLine();
while(line != null) {
System.out.println(line);
line = br.readLine();
}
br.close();
input.close();
httpCon.disconnect();
}
}
5.网编应用实例-博客浏览量
/**
* 思路:通过HttpConnection 访问对应IP。访问速度不能太快,因为CSDN在短时间内不会将同一个IP访问请求记录在内
* 因此我们可以使用线程睡眠方法,控制浏览速度。
* 首先需要获得每篇博文的URL
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
class URLPassage {
private static ArrayList<String> URLA = new ArrayList<String>();
private static int URL_LENGTH = 0;
private static String[] urlA = null;
public static String[] getBlogsURL() throws IOException {
ArrayList<URL> url = new ArrayList<URL>();
int index = 0, count = 0;
url.add(new URL("https://blog.csdn.net/qq_42017331/article/list/1?"));//添加博客主页
url.add(new URL("https://blog.csdn.net/qq_42017331/article/list/2?"));
for (URL u : url) {
getBlogsURL(u);
}
urlA = new String[URL_LENGTH / 2];
for(String x : URLA) {
count++;
if(count % 2 == 0) {
urlA[index++] = x;
}
}
return urlA;
}
public static void getBlogsURL(URL url) throws IOException {
HttpURLConnection htCon = (HttpURLConnection) url.openConnection();
InputStream input = htCon.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(input));
String line = br.readLine();
while (line != null) {
line = line.trim();
if (line.contains("https://blog.csdn.net/qq_42017331/article/details/")) {
line = line.substring(9, 67);
URLA.add(line);
URL_LENGTH++;
}
line = br.readLine();
}
}
}
public class BrowsingTest implements Runnable {
private String[] urlA= null;
private URL url = null;
private HttpURLConnection htCon = null;
private InputStream input = null;
private InputStreamReader read = null;
public BrowsingTest() throws IOException {
new URLPassage();
urlA = URLPassage.getBlogsURL();
}
public void run() {
try {
for(int i = 0; i < 100000; i++) {
url = new URL(urlA[i % urlA.length]);
htCon = (HttpURLConnection) url.openConnection();
input = htCon.getInputStream();
read = new InputStreamReader(input);
if(read.read() > 0) {
Thread.sleep(800);//设置时间
System.out.println( i + " success...");
} else {
System.out.println( i + " fail...");
}
if(i % urlA.length == 0 && i != 0) {
Thread.sleep(15000);//设置时间
}
input.close();
read.close();
htCon.disconnect();
}
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Thread th = new Thread(new BrowsingTest());
th.start();
}
}