网络基础(非重点)
学习Java网络编程首先需要对网络基础有一定了解,要了解网络类型,TCP/IP协议族,IP地址和端口,域名和DNS,重点介绍一下IP地址和端口吧!
IP地址和端口
IP地址被分成A,B,C,D,E五类,分别适用于大型网络,中型网络,小型网络,多目地址以及备用。
- A类地址:最大网络数-126(2^7-2), IP地址范围-0.0.0.0~127.255.255.255,最大主机数-16777214,私有IP地址范围-10.0.0.0 ~10.255.255.255,,默认网络掩码是-255.0.0.0
- B类地址:最大网络数-16384(2^14), IP地址范围-128.0.0.0~191.255.255.255,最大主机数-65534,私有IP地址范围-172.16.0.0 ~172.31.255.255,默认网络掩码是-255.255.0.0
- C类地址:最大网络数-2097152(2^21), IP地址范围-192.0.0.0~223.255.255.255,最大主机数-254,私有IP地址范围-192.168.0.0 ~192.168.255.255,,默认网络掩码是-255.255.255.0
注意:IP地址中不能以十进制“127”作为开头,该类地址中的数字127.0.0.1 ~127.255.255.255用于回路测试,如127.0.0.1可以作为本机IP地址,用“http://127.0.0.1"就可以测试本机中配置的Web服务器。
常用端口及服务
端口号 | 服务 |
---|---|
7 | Echo服务端口 |
21 | FTP服务端口 |
23 | Telnet服务端口 |
25 | SMTP服务端口 |
80 | HTTP服务端口 |
443 | HTTPS服务端口 |
基于TCP网络编程
InetAddress类
Java提供的InetAddress类来封装IP地址和域名
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressDemo {
public static void main(String[] args) {
try {
InetAddress localIp=InetAddress.getLocalHost();//获取本机地址信息
System.out.println(localIp.getCanonicalHostName());
System.out.println(localIp.getHostAddress());
System.out.println(localIp.isReachable(5000));//判读是否为可达地址
InetAddress baiduIp=InetAddress.getByName("www.baidu.com");//获取百度的地址信息
System.out.println(baiduIp.getCanonicalHostName());
System.out.println(baiduIp.getHostAddress());
System.out.println(baiduIp.isReachable(5000));//判读是否为可达地址
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意 -InetAddress类无构造方法,因此不能之间创建对象,而是通过该类的静态方法来创建InetAddress对象。
Socket类
使用Socket套接字可以较为方便地在网络上传输数据,从而实现两台计算机之间地通信
ServerSocket类
ServerSocket是服务器套接字,运行在服务器端,通过指定端口主动监听来自客户端的Socket连接,当客户端发送Socket请求并与服务器建立连接时,服务器将验证并接受客户端的Socket,从而建立客户端与服务器之间的网络虚拟链路,一旦两端的实体之间建立了虚拟链路,就可以相互传送数据了。
使用Socket进行网络通信的两个关键类
- 客户端:ClientSocketDemo
import java.io.*;
import java.net.Socket;
public class ClientSocketDemo {
public static void main(String[] args) {
try {
//创建连接到本机、端口为28888的Socket的对象
Socket socket=new Socket("127.0.0.1",28888);
//将Socket对应的输出流包装成PrintStream
PrintStream printStream=new PrintStream(socket.getOutputStream());
//往服务器发送消息
//也可以写成是outputStream.write("我是Mark_ZQP")
printStream.println("我是MarkZ_QP");
printStream.flush();
//将Socket对应的输入流包装成BufferedReader
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//读取服务器返回的信息并显示
String line=bufferedReader.readLine();
System.out.println("来自服务器的数据:"+line);
//关闭
bufferedReader.close();
printStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 服务器端:ServerSocket类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerSocketDemo extends Thread {
//声明一个ServerSocket
ServerSocket serverSocket;
int num=0;
public ServerSocketDemo(){
try {
//创建ServerSocket,用于监听28888端口是否有客户端的Socket
serverSocket=new ServerSocket(28888);
} catch (IOException e) {
e.printStackTrace();
}
//启动当前线程,即执行run()方法
this.start();
System.out.println("服务器启动!!");
}
public void run(){
while (this.isAlive()){
try {
//接收客户端的Socket
Socket socket=serverSocket.accept();
//将Socket对应的输入流包装成BufferedReader
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 下面这里也是一种读取客户端发来数据的方法
//byte[] buff = new byte[1024];
//InputStream in = socket.getInputStream()
//int len = in.read(buff);
// if(len > 0){ String msg = new String(buff, 0, len); }
//读取客户端发送的信息并显示
String line=bufferedReader.readLine();
System.out.println(line);
//将Socket对应的输出流包装成PrintStream
PrintStream printStream=new PrintStream(socket.getOutputStream());
//往客户端发送消息
printStream.println("你是第"+(++num)+"个访问服务器的用户");
//这样也可以往客户端写数据
//OutputStream os = socket.getOutputStream();//先拿到客户端的输出流
// String returnMsg = "向客户端写数据";
// os.write(returnMsg.getBytes());
// os.flush();
// os.close();
//关闭
printStream.flush();;
bufferedReader.close();
printStream.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new ServerSocketDemo();
}
}
上述代码服务器端是一个多线程应用程序,能为多个客户端提供服务。在ServerSocketDemo构造方法中,先创建一个用于监听28888端口的ServerSocket对象,再调用this.start()方法启动线程。在线程的run()方法中,先调用ServerSocket对象的accpet()方法来接收客户端发送的Socket对象,再使用getInputStream()获取Socket对象的输入流,用于读取客户端发送的数据信息;然后使用getOutputStream获取Socket对象的输出流,往客户端发送信息;最后关闭输入,输出和Socket,释放所有资源。
程序启动先启动服务器端代码,再启动客户端代码。