JAVA通信杂谈

Java中的网络支持

针对网络通信的不同层次,Java提供的网络功能有四大类
  • InetAddress:用于标识网络上的硬件资源
  • URL:统一资源定位符 通过URL可以直接读取或写入网络上的数据。
  • Sockets:使用TCP协议实现网络通信的Socket相关的类
  • Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信。

InetAddress类

  • InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
* Created by Anber on 2017/11/1.
* InetAddress类
*/
public class test01 {

public static void main(String[] args) {
//获取本机的InetAddress实例
try {
InetAddress address = InetAddress.getLocalHost();
System.out.println("计算机名:" + address.getHostName());
System.out.println("IP地址:" + address.getHostAddress());
byte[] bytes = address.getAddress();
System.out.println("字节数组形式的IP地址:"+ Arrays.toString(bytes));
System.out.println(address);
//根据主机名获取InetAddress实例
// InetAddress address2 = InetAddress.getByName("suxiaoliangdeMacBook-Pro.local");
//根据IP地址获取InetAddress实例
InetAddress address2 = InetAddress.getByName("192.168.0.115");
System.out.println("计算机名:" + address2.getHostName());
System.out.println("IP地址:" + address2.getHostAddress());
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}

URL

  • URL(Uniform Resoure Locator)统一资源定位符,表示Internet上某一资源的地址。
  • URL有两个部分组成:协议名称和资源名称,中间用冒号隔开。
  • 在java.net 包中,提供了URL类来表示URL。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.webSocket;

import java.net.MalformedURLException;
import java.net.URL;

/**
* Created by Anber on 2017/11/1.
* URL常用方法
*/
public class test02 {
public static void main(String[] args) {
try {
//创建一个URL的实例
URL baidu = new URL("https://www.baidu.com");
//?后面表示参数,#后面表示锚点
URL url = new URL(baidu, "/index.html?username=username#test");
System.out.println("协议:"+url.getProtocol());
System.out.println("主机:"+url.getHost());
//如果未指定端口号,则使用默认的端口号,此时getProt()方法返回值未-1
System.out.println("端口:"+url.getPort());
System.out.println("文件路径:"+url.getPath());
System.out.println("文件名:"+url.getFile());
System.out.println("相对路径:"+url.getRef());
System.out.println("查询字符串:"+url.getQuery());
} catch (MalformedURLException e) {
e.printStackTrace();
}

}
}

使用URL读取网页内容

  • 通知URL对象的openStream()方法可以得到指定资源的输入流
  • 通过输入流可以读取、访问网络上的数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.webSocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;

/**
* Created by Anber on 2017/11/1.
* 使用URL读取网页内容
*/
public class test03 {
public static void main(String[] args) {
try {
//创建一个URL实例
URL url = new URL("http://www.baidu.com");
//通过URL的openStream方法获取URL对象所表示的资源的字节流
InputStream is = url.openStream();
//将字节输入流转换为字符输入流
InputStreamReader isr = new InputStreamReader(is,"utf-8");
//为字符输入流添加缓冲
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();//读取数据
while (data != null){//循环读取数据
System.out.println(data);//输出数据
data = br.readLine();
}
br.close();
isr.close();
is.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Socket通信

TCP协议是面向连接、可靠的、有序的,以字节流的方式发送数据
基于TCP协议实现网络通信的类
  • 客户端的Socket类
  • 服务器端的ServerSocket类
Socket通信实现步骤
  1. 创建ServerSocket和Socket
  2. 打开连接到Socket的输入/输出流
  3. 按照协议对Socket进行读/写操作
  4. 关闭输入输出流、关闭Socket
服务器端
  1. 创建ServerSocket对象,绑定监听端口
  2. 通过accept()方法监听客户端请求
  3. 连接建立后,通过输入流读取客户端发送的请求信息
  4. 通过输出流向客户端发送响应信息
  5. 关闭相关资源
客户端
  1. 创建Socket对象,指明需要连接的服务器的地址和端口号
  2. 连接建立后,通过输出流向服务器端发送请求信息
  3. 通过输入流获取服务器响应的信息
  4. 关闭相关资源
多线程服务器
应用多线程来实现服务器与多客户端之间的通信
基本步骤
  1. 服务器端创建ServerSocket,循环使用accept()等待客户端的连接
  2. 客户端创建一个Socket并请求和服务端连接
  3. 服务端接受客户端请求,创建socket与该客户建立专线连接
  4. 建立连接的两个socket在一个单独的线程对话
  5. 服务器端继续等待新的连接
客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.webSocket;

import java.io.*;
import java.net.Socket;

/**
* Created by Anber on 2017/11/1.
* 客户端
*/
public class Client {
public static void main(String[] args) {

try {
//1.创建客户端Socket,指定服务器地址和端口
Socket socket = new Socket("localhost", 8888);
//2.获取输出流,向服务器端发送信息
OutputStream os = socket.getOutputStream();//字节输出流
PrintWriter pw = new PrintWriter(os);//将输出流包装为打印流
pw.write("用户名:admin;密码:456");
pw.flush();
socket.shutdownOutput();//关闭输出流
//3.获取输入流,并读取服务器端的响应信息
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is,"utf-8");
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();
while (data != null){
System.out.println("我是客户端,服务器说"+data);
data = br.readLine();
}
//3.关闭资源
br.close();
isr.close();
is.close();
pw.close();
os.close();
socket.close();

} catch (IOException e) {
e.printStackTrace();
}

}
}
多线程类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package com.webSocket;

import java.io.*;
import java.net.Socket;

/**
* Created by Anber on 2017/11/2.
* 服务器线程处理类
*/
public class ServerThread extends Thread {
//和本线程相关的Socket
Socket socket = null;

InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;

OutputStream os = null;
PrintWriter pw = null;
public ServerThread(Socket socket){
this.socket = socket;
}
//线程执行的操作,响应客户端的请求
public void run(){

try {
//获取输入流,并读取客户端的信息
is = socket.getInputStream();
isr = new InputStreamReader(is, "utf-8");
br = new BufferedReader(isr);
String data = br.readLine();
while (data != null) {
System.out.println("我是服务端,客户端说" + data);
data = br.readLine();
}
socket.shutdownInput();//关闭输入流
//获取输出流,响应客户端的请求
os = socket.getOutputStream();
pw = new PrintWriter(os);//包装为打印流
pw.write("欢迎您!");
pw.flush();//调用flush()方法将缓冲输出


} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
//关闭相关的资源
if(pw != null){
pw.close();
}
if(os != null){
os.close();
}
if(br != null){
br.close();
}
if(isr != null){
isr.close();
}
if(is != null){
is.close();
}
if(socket != null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}



}
}
服务器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.webSocket;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
* Created by Anber on 2017/11/1.
* 基于TCP协议的Socket通信,实现用户登录
* 服务器端
*/
public class Server {
public static void main(String[] args) {
try {
//1.创建一个服务器端Socket,即ServerSocket,指定绑定的端口,并监听此端口
ServerSocket serverSocket = new ServerSocket(8888);
//2.调用accept()方法开始监听,等待客户端的连接
System.out.println("***服务器即将启动,等待客户端的连接***");
Socket socket = null;
//记录客户端的数量
int count = 0;
//循环监听等待客户端的连接
while (true){
socket = serverSocket.accept();
//创建一个新的线程
ServerThread serverThread = new ServerThread(socket);
//启动线程
serverThread.start();
count++;//统计客户端的数量
System.out.println("输出客户端的数量:"+count);
InetAddress address = socket.getInetAddress();
System.out.println("当前客户端的IP:"+address.getHostAddress());
}

} catch (IOException e) {
e.printStackTrace();
}
}
}