Java登陆第十二天——网络编程(二)InetAddress、Socket
Java提供了java.net包,专门用来进行网络开发。
InetAddress
InetAddress类主要表示IP地址。InetAddress类常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
public static InetAddress getByName(String host) throws UnknownHostException | 静态方法 | 根据域名/主机名得到InetAddress对象 |
public static InetAddress getLocalHost() throws UnknownHostException | 静态方法 | 获取本机的InetAddress对象 |
public String getHostName() | 普通方法 | 获取主机名 |
public String getHostAddress() | 普通方法 | 获取IP地址 |
public boolean isReachable(int timeout) throws IOException | 普通方法 | 判断地址是否可以访问,并传入超时时间 |
栗子:测试InetAddress类常用方法
代码如下:
public static void main(String[] args) {
try {
InetAddress localHost = InetAddress.getLocalHost();
System.out.println("本机InetAddress对象信息:"+localHost);
System.out.println("本机主机名:"+localHost.getHostName());//因为InetAddress构造方法私有化
System.out.println("本机IP地址:"+localHost.getHostAddress());//所以只能通过这种方式调用其普通方法
InetAddress byName = InetAddress.getByName("www.bilibili.com");//通过域名获取InetAddress对象
System.out.println("是否可以访问:"+byName.isReachable(5000));//ms为单位 5000ms=5s
} catch (IOException e) {
e.printStackTrace();
}
}
程序运行结果:
本机InetAddress对象信息:DESKTOP-Q99QTUH/172.220.44.93
本机主机名:DESKTOP-Q99QTUH
本机IP地址:172.220.44.93
是否可以访问:true
之前域名说过,localhost是一个特殊的域名。
栗子:测试localhost特殊域名
代码如下:
public static void main(String[] args) {
try {
InetAddress localhost = InetAddress.getByName("localhost");
System.out.println(localhost);
} catch (IOException e) {
e.printStackTrace();
}
}
程序运行结果:
localhost/127.0.0.1
Socket
使用Socket(套接字)可以进行TCP程序的开发,此类可以建立双向地、可靠地、持续地通信连接。
服务端使用ServerSocket类等待客户端连接。每一个客户端都是一个Socket对象。
ServerSocket
ServerSocket类主要是编写服务端程序,用于接收客户端请求。常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
public ServerSocket(int port) throws IOException | 构造方法 | 监听指定端口 |
public Socket accept() throws IOException | 普通方法 | 等待客户端请求并返回Socket对象(没有会一直阻塞) |
public InetAddress getInetAddress() | 普通方法 | 返回服务器IP地址 |
public void close() throws IOException | 普通方法 | 关闭服务端 |
栗子:编写一个本机的服务端,端口为8888
服务端,Test24server类:
//服务端,Test24server类
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("成功创建服务端对象,接下来监听8888端口");
serverSocket.accept();
//若无客户端访问8888端口,程序就会阻塞在此;若有客户端访问8888端口,创建并返回一个Socket对象。
System.out.println("1");//若执行到此证明不会阻塞
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
程序运行结果:
成功创建服务端对象,接下来监听8888端口
//阻塞中....
服务端每次运行时都会调用accept()方法等待客户端连接,此方法会一直阻塞,直到客户端连接之后程序才会继续向下执行。该方法返回值是一个Socket对象。
Socket
每一个Socket对象都代表一个客户端对象。Socket类常用方法如下:
方法 | 类型 | 描述 |
---|---|---|
public Socket(String host, int port, InetAddress localAddr,int localPort) throws IOException | 构造方法 | 连接服务端的主机名及端口 |
public OutputStream getOutputStream() throws IOException | 普通方法 | 获取该客户端的输出流 |
public void shutdownOutput() throws IOException | 普通方法 | 输出结束 |
public InputStream getInputStream() throws IOException | 普通方法 | 获取该客户端的输入流 |
public void shutdownInput() throws IOException | 普通方法 | 输入结束 |
栗子:继续使用服务端栗子,客户端连接至服务端。
服务端,Test24server类:
//服务端,Test24server类
public class Test24server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("成功创建服务端对象,接下来监听8888端口");
serverSocket.accept();
//若无客户端访问8888端口,程序就会阻塞在此;若有客户端访问8888端口,创建并返回一个Socket对象。
System.out.println("1");//若执行到此证明不会阻塞
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端,Test24client类:
//客户端,Test24client类
public class Test24client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);//访问本机8888端口
System.out.println("连接服务端成功,啥事不干只连接");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
程序运行结果:
栗子:客户端访问本机8888端口,并输出hello,world
服务端利用accpet()方法返回的Socket对象读取内容
客户端,Test24client类:
//客户端,Test24client类
public class Test24client {
public static void main(String[] args) {
try {
Socket socket = new Socket("localhost", 8888);
OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());//字节、字符输出都可以
writer.write("hello,world");
writer.flush();//一定要手动提交缓冲区内容!!!
socket.shutdownOutput();//告诉服务端输出完毕,不用继续等待了。一定一定一定!!!
writer.close();//资源类一定要使用后就关闭!
socket.close();
System.out.println("1");//证明运行到此
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端,Test24server类:
//服务端,Test24server类
public class Test24server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端启动成功,监听8888端口");
Socket socket = serverSocket.accept();//获取客户端的Socket对象
InputStreamReader reader = new InputStreamReader(socket.getInputStream());//什么流输出什么流读取
char[] chars = new char[1024];
int i;
while ( (i = reader.read(chars) ) !=-1 ){
System.out.println(new String(chars,0,i));
}
socket.shutdownInput();//读取完毕
reader.close();
serverSocket.close();
System.out.println("1");
} catch (IOException e) {
e.printStackTrace();
}
}
}
程序运行结果:
栗子:客户端给本机服务端8888发送一张图片
服务端接收到图片后,回复"收到图片"
客户端接收服务端回复的消息
退出
客户端,Test24client类:
//客户端,Test24client类
public class Test24client {
public static void main(String[] args) {
File file = new File("D:\\IOtest\\finger.jpg");
try {
Socket socket = new Socket("localhost", 8888);
System.out.println("发送图片");
BufferedOutputStream socketOut = new BufferedOutputStream(socket.getOutputStream());
FileInputStream filein = new FileInputStream(file);
int i;
byte[] bytes = new byte[1024];
while ( (i=filein.read(bytes))!=-1 ){//文件流读取,socket输出流输出
socketOut.write(bytes,0,i);
socketOut.flush();
}
socket.shutdownOutput();//输出结束
BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream());//服务端接收到图片后,会发送消息
while ( (i=inputStream.read(bytes))!=-1 ){//文件流读取,socket输出流输出
System.out.println(new String(bytes,0,i));
}
socket.shutdownInput();//输出结束
inputStream.close();//后开启的先关闭
filein.close();
socketOut.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务端,Test24server类:
//服务端,Test24server类
public class Test24server {
public static void main(String[] args){
File file = new File("D:\\Code\\Maven\\src\\main\\resources\\finger.jpg");
try {
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = serverSocket.accept();
System.out.println("接收图片");
BufferedInputStream inputStream = new BufferedInputStream(socket.getInputStream());
FileOutputStream fileout = new FileOutputStream(file);
int i;
byte[] bytes = new byte[1024];
while ( (i=inputStream.read(bytes))!=-1 ){//socket输入流读取,文件流输出
fileout.write(bytes,0,i);
}
socket.shutdownInput();//输入结束
BufferedOutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
outputStream.write("收到图片".getBytes());//返回消息
outputStream.flush();//一定要刷新!!
socket.shutdownOutput();//输出结束
outputStream.close();//后开启的先关闭
fileout.close();
inputStream.close();
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
程序运行结果: