InetAddress 根据域名得到IP地址或名称
没有构造方法,通过:
(1)InetAddress i1 =InetAddress.getByName(String)返回一个InetAddress实例。
(2)如果一个地址有多个ip地址,比如google,有3个ip地址,就调用InetAddress[] i2 =
InetAddress.getAllByName(String);
InetAddress.getLocalhost()获得本机的InetAddress实例。
package Day22_net;
import java.io.IOException;
import java.net.InetAddress;
/**
* @author Aoman_Hao
*/
public class InetTest {
public static void main(String[] args) throws IOException {
//提供主机名获取主机的IP
InetAddress byName = InetAddress.getByName("AomanHao");
System.out.println("主机IP:"+byName);
//提供主机IP获取主机名,主机IP是之前返回值
String hostName = byName.getHostName();
System.out.println("主机名:"+hostName);
}
}
输出:
主机IP:AomanHao/192.168.0.111
主机名:AomanHao
Java网络程序都建立在TCP/IP协议基础上,在应用层实现。传输层向应用层提供了套接字Socket接口,Socket封装了下层的数据传细节,应用层的程序通过Socket来建立与远程主机的连接,以及数据传输,如下图所示:
UDP协议
- UDP协议(发送端和接收端),不需要建立连接通道
发送端 步骤:
1)创建UDP协议发送端的Socket对象
2)创建数据报包:通过这个数据包将数据发送到接收端
3)调用UDP协议发送端发送的方法
4)关闭资源
UDP协议的接收端
1)创建接收端的Socket对象
2)创建一个数据报包接收发送端发送来的数据报包(接收容器)
4)解析数据报包里面的实际数据,显示在控制台上
5)关闭资源
发送类:
package Day22_net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author Aoman_Hao
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
//创建Socket对象
DatagramSocket ds = new DatagramSocket();
//创建InetAddress对象,Ip地址对象
InetAddress address = InetAddress.getByName("192.168.0.111") ;
//发送数据内容
String s = "刘诗诗最美丽";
byte[] by = s.getBytes();
//创建数据报包
DatagramPacket dp = new DatagramPacket(by, by.length, address, 55);
//调用send方法
ds.send(dp);
//关闭
ds.close();
}
}
接收类:
package Day22_net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author Aoman_Hao
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建Socket对象 ----datagramsocket
DatagramSocket ds = new DatagramSocket(55);
byte[] by = new byte[1024];
// 创建数据报包----datagrampacket
DatagramPacket dp = new DatagramPacket(by, by.length);
// 调用接收方法 ---receive
ds.receive(dp);
// 解析数据
// 通过数据报包得到IP对象,地址
InetAddress address = dp.getAddress();
String hostAddress = address.getHostAddress();
// 解析数据---getdata
byte[] by1 = dp.getData();
int length = dp.getLength();
// 重建字符串
String s = new String(by1, 0, length);
System.out.println(s);
ds.close();
}
}
注:先运行接收端,在运行发送端
输出:
刘诗诗最美丽
接收类的receive采用阻塞式方法(即等待发送端发送数据,只要没有数据,就一直等待,有数据的话将数据显示控制)
循环录入,屏幕录入数据的效果
发送端:
package Day22_net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
*
* 屏幕录入数据,udp发送,接收
* @author Aoman_Hao
*/
public class SendDemo2 {
public static void main(String[] args) throws IOException {
// 创建socket对象
DatagramSocket s = new DatagramSocket();
// 用IO流屏幕录入数据,有readline方法可用
BufferedReader sd = new BufferedReader(new InputStreamReader(System.in));
// 循环录入,一句一句录入
String line = null;
while ((line = sd.readLine()) != null) {
byte[] by = line.getBytes();
// 创建数据报包
DatagramPacket dp = new DatagramPacket(by, by.length,
InetAddress.getByName("192.168.0.111"), 55);
s.send(dp);
}
s.close();
sd.close();
}
}
接收端:
package Day22_net;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/**
* @author Aoman_Hao
*/
public class ReceiveDemo2 {
public static void main(String[] args) throws IOException {
//创建socket对象,输入对应端口
DatagramSocket ds = new DatagramSocket(55);
byte[] by = new byte[1024];
//创建数据报包
DatagramPacket dp = new DatagramPacket(by, by.length);
while(true){
//接收数据
ds.receive(dp);
//解析数据 getData,getLength
byte[] bs = dp.getData();
int length = dp.getLength();
String s = new String(bs, 0, length);
//读取发送端IP地址
String hostAddress = dp.getAddress().getHostAddress();
System.out.println("IP地址"+hostAddress+"发送"+s);
}
}
}
注:接收端要不停接收数据,不需要关闭
输出:
(发送端):
刘诗诗美丽
蓉儿更美
(接收端):
IP地址192.168.0.111发送刘诗诗美丽
IP地址192.168.0.111发送蓉儿更美
TCP网络编程
构造方法:
ServerSocket() ~创建非绑定服务器套接字。
ServerSocket(int port) ~创建绑定到特定端口的服务器套接字。
ServerSocket(int port, int backlog) ~利用指定的 backlog
创建服务器套接字并将其绑定到指定的本地端口号。ServerSocket(int port, int backlog, InetAddress bindAddr) ~使用指定的端口、侦听
backlog 和要绑定到的本地 IP 地址创建服务器。
> import java.io.InputStream; import java.net.ServerSocket; import
> java.net.Socket;
/**
* @author Aoman_Hao
*/
public class TcpServerDemo {
public static void main(String[] args) throws IOException {
// 构造服务器端的socket对象
ServerSocket ss = new ServerSocket(5);
// 创建监听对象
Socket s = ss.accept();
// 创建输入流对象
InputStream is = s.getInputStream();
// 遍历读取数据,read()方法读取
while (true) {
byte[] by = new byte[1024];
int len = is.read(by);
String s1 = new String(by, 0, len);
System.out.println(s1 + "\t树洞准奏");
}
// 服务器端一直工作,不需要关闭流
}
}
客户端:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
/**
* TCP 客户端,服务器端通信互联(屏幕录入数据)
* @author Aoman_Hao
*/
public class TcpClientDemo {
public static void main(String[] args) throws IOException {
// 构造客户端的socket对象
Socket s = new Socket("192.168.0.111", 5);
// 屏幕录入打印输出流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输出你的祝福或者愿望给树洞,回复“0”结束说话");
// 读取输出流
OutputStream os = s.getOutputStream();
// 遍历写在流中
String line = null;
// 判断如果只输入字符“0”则退出输出入,退出客户端
while ((line = br.readLine()) != null) {
if (line.equals("0") ) {
break;
} else {
os.write(line.getBytes());
}
}
// 关闭流
br.close();
os.close();
}
}
输入:
输出你的祝福或者愿望给树洞,回复“0”结束说话
aa
0
输出:
aa 树洞准奏
但是报错java.lang.StringIndexOutOfBoundsException: String index out of range: -1
可能跟客户端判断输入信息有关
多线程案例尝试通信
客戶端:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* 客户端需要两个流,一个输出流给服务器端传送数据,一个输入流读取服务器端的反馈(用线程类写)
*
* @author Aoman_Hao
*/
public class CRClientDemo {
public static void main(String[] args) throws IOException{
//建立socket对象
Socket s = new Socket("192.168.0.111", 5000);
//输入流,读取服务器的数据用新建线程类 new Thread(new target)
new Thread(new ClientThread(s)).start();
//输出流,数据写给服务器
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//读键盘录入的数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("输入录入数据:");
//遍历
String line = null;
while((line = br.readLine())!=null){
//数据输出到流中
bw.write(line);
bw.flush();
}
bw.close();
s.close();
}
}
客戶端綫程類
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
/**
* @author Aoman_Hao
*/
public class ClientThread implements Runnable{
private Socket s;
BufferedReader br = null ;
public ClientThread() {
super();
}
public ClientThread(Socket s) throws IOException{
this.s = s;
}
@Override
public void run() {
String line = null;
try {
//构造输入流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取流中的数据
while((line = br.readLine())!=null){
System.out.println("服务器回馈:"+line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author Aoman_Hao
*/
public class CRServerDemo {
public static void main(String[] args) throws IOException {
// 建立socket对象
ServerSocket ss = new ServerSocket(5000);
// 建立监听对象
Socket s = ss.accept();
// 输入流用线程类
Thread T_Server = new Thread(new ServerThread(s), "服务器端读数据");
T_Server.start();
}
}
服务器端线程类:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* @author Aoman_Hao
*/
public class ServerThread implements Runnable{
private Socket s;
// private BufferedReader br = null ;
// private BufferedWriter bw = null ;
public ServerThread() {
super();
}
//有参构造
public ServerThread(Socket s) throws IOException{
this.s = s;
}
@Override
public void run() {
String line = null;
try {
//读取流中客户端发来的数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
// 输出流,反馈给客户端
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
while((line = br.readLine()) != null){
System.out.println("客户端数据:"+line+"\r\n");
bw.write(line+"\t录入");
bw.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端读取文件,服务器端显示数据
客户端:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* @author Aoman_Hao
*/
public class JCClientDemo {
public static void main(String[] args) throws IOException{
//创建socket对象
Socket s = new Socket("192.168.0.111",5000);
//文件字节流缓冲流
BufferedReader br = new BufferedReader(new FileReader("D:\\Java\\JavaTest\\Aoman_3.txt"));
//socket的输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//遍历 不能用byte
String line = null;
while((line = br.readLine())!= null){
//写在输出流中
bw.write(line);
bw.flush();
}
bw.close();
s.close();
}}
服务器端:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* 需求:客户端一个文本文件,服务器端将客户端文本文件中的内容展示到控制台上
* @author Aoman_Hao
*/
public class JCServerDemo {
public static void main(String[] args) throws IOException{
//创建socket对象
ServerSocket ss = new ServerSocket(5000);
//监视socket对象数据
Socket s = ss.accept();
//输入流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//展示在控制台
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
}
}