InetAddress 类
public static void main(String[] args) throws UnknownHostException {
InetAddress localhost = InetAddress.getLocalHost();
System.out.println("localhost = " + localhost);
InetAddress host1 = InetAddress.getByName("BLACK");
System.out.println("host1 = " + host1);
InetAddress host2 = InetAddress.getByName("www.baidu.com");
System.out.println("host2 = " + host2);
String hostAddress = host2.getHostAddress();
System.out.println("hostAddress = " + hostAddress);
String hostName = host2.getHostName();
System.out.println("hostName = " + hostName);
}
输出结果:
localhost = Black/192.168.199.99
host1 = Black/192.168.199.99
host2 = www.baidu.com/14.215.177.39
hostAddress = 14.215.177.39
hostName = www.baidu.com
Socket
Socket 套接字应用广泛,是事实上网络通信的标准
- 通信的两端都要有 Socket,是两台机器通信的端点
- 网络通信其实就是 Socket 的通信
- Socket 允许程序把网络连接当成一个流,数据在两个 Socket直接通过 IO 传输
- 一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端
编程方式有两种
TCP 网络通信编程
- 基于客户端-服务端的网络通信
- 底层使用 TCP/IP 协议
- 是基于 Socket 的 TCP 编程
例子1: 服务器监听 9999 端口,客户端连接服务端,向服务端发送字节流的消息,然后服务端显示请求内容 服务端:
public class SocketTCPServer01 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端在监听 9999 端口,等待连接");
Socket socket = serverSocket.accept();
System.out.println("服务器端 socket = " + socket);
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));
}
inputStream.close();
socket.close();
serverSocket.close();
System.out.println("服务器退出");
}
}
客户端:
public class SocketTCPClient01 {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket = " + socket);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("杰瑞狗666".getBytes());
outputStream.close();
socket.close();
System.out.println("客户端退出");
}
}
例子2: 在上个例子的基础上,让服务端收到客户端的字节流信息后,给客户端回复字节流的信息,客户端将收到的内容打印出来。注意:需要在输出流之后加上结束标记,关闭TCP连接
服务端
public class SocketTCPServer02 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端在监听 9999 端口,等待连接");
Socket socket = serverSocket.accept();
System.out.println("服务器端 socket = " + socket);
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));
}
OutputStream outputStream = socket.getOutputStream();
outputStream.write("hello杰瑞狗".getBytes());
socket.shutdownOutput();
inputStream.close();
outputStream.close();
socket.close();
serverSocket.close();
System.out.println("服务器退出");
}
}
客户端
public class SocketTCPClient02 {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket = " + socket);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("杰瑞狗666".getBytes());
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
byte[] buf = new byte[1024];
int readLen = 0;
while ((readLen = inputStream.read(buf)) != -1) {
System.out.println(new String(buf, 0, readLen));
}
outputStream.close();
inputStream.close();
socket.close();
System.out.println("客户端退出");
}
}
例子3: 在第二个例子的基础上,使用字符流完成消息的发送接收
服务端:
public class SocketTCPServer03 {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务端在监听 9999 端口,等待连接");
Socket socket = serverSocket.accept();
System.out.println("服务器端 socket = " + socket);
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println("s = " + s);
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("回复杰瑞狗777 字符流");
bufferedWriter.newLine();
bufferedWriter.flush();
bufferedWriter.close();
bufferedReader.close();
socket.close();
serverSocket.close();
System.out.println("服务器退出");
}
}
客户端:
public class SocketTCPClient03 {
public static void main(String[] args) throws IOException {
Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
System.out.println("客户端 socket = " + socket);
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
bufferedWriter.write("杰瑞狗666 字符流");
bufferedWriter.newLine();
bufferedWriter.flush();
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String s = bufferedReader.readLine();
System.out.println("s = " + s);
bufferedReader.close();
bufferedWriter.close();
socket.close();
System.out.println("客户端退出");
}
}
例子 4: 使用客户端读取图片发送给服务端,服务端收到后回复字符流的消息
服务端:
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端在监听 8888 端口");
Socket accept = serverSocket.accept();
BufferedInputStream bufferedInputStream = new BufferedInputStream(accept.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
String filePath = "src\\cat.jpg";
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath));
bufferedOutputStream.write(bytes);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bufferedWriter.write("服务器收到图片");
bufferedWriter.newLine();
bufferedWriter.flush();
bufferedWriter.close();
bufferedOutputStream.close();
bufferedInputStream.close();
accept.close();
serverSocket.close();
}
客户端:
public static void main(String[] args) throws Exception {
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
String filePath = "e:\\cat.jpg";
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(filePath));
byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());
bufferedOutputStream.write(bytes);
socket.shutdownOutput();
BufferedInputStream bufferedInputStream1 = new BufferedInputStream(socket.getInputStream());
String s = StreamUtils.streamToString(bufferedInputStream1);
System.out.println("客户端收到回复:" + s);
bufferedInputStream.close();
bufferedInputStream1.close();
bufferedInputStream.close();
socket.close();
}
工具类 StreamUtils:
public static byte[] streamToByteArray(InputStream is) throws Exception{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int len;
while((len=is.read(b))!=-1){
bos.write(b, 0, len);
}
byte[] array = bos.toByteArray();
bos.close();
return array;
}
public static String streamToString(InputStream is) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder= new StringBuilder();
String line;
while((line=reader.readLine())!=null){
builder.append(line+"\r\n");
}
return builder.toString();
}
TCP 其它知识点
- 客户端也是通过端口与服务器进行通信的,端口是 TCP/IP 协议分配的,不是确定的
比如在上面的例子 4 中,在获取客户端连接后加上一句输出语句,可以看到客户端的 socket 的信息,里面包含端口号:
UDP
- 类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议的网络程序
- UDP 数据报通过数据报套接字 DatagramSocket 发送和接受,系统不保证一定能到达目的地,也不保证到达的时间
- DatagramPacket 对象封装了 UDP 数据报,在数据报中包含了发送端和接收端的 IP 地址以及端口
- UDP 协议中每个数据报都给出了完整的地址信息,所以无需建立连接
原理示意图:
例子 1: 发送端向接收到发送消息,接收端收到消息后发送回复后退出,发送端收到回复后退出
发送端:
public class UDPSender01 {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(7777);
byte[] data = "杰瑞狗7777".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.125.29"), 9999);
datagramSocket.send(datagramPacket);
byte[] replyData = new byte[1024];
DatagramPacket packet = new DatagramPacket(replyData, replyData.length);
datagramSocket.receive(packet);
int len = packet.getLength();
byte[] data2 = packet.getData();
String s = new String(data2, 0, len);
System.out.println("s = " + s);
datagramSocket.close();
System.out.println("发送端退出");
}
}
接收端:
public class UDPReciever01 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(9999);
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
System.out.println("接收端等待接收数据");
socket.receive(packet);
int len = packet.getLength();
byte[] data = packet.getData();
String s = new String(data, 0, len);
System.out.println("s = " + s);
byte[] replyData = "已收到杰瑞给777".getBytes();
DatagramPacket packet1 = new DatagramPacket(replyData, replyData.length, InetAddress.getByName("192.168.125.29"), 7777);
socket.send(packet1);
System.out.println("接收端退出");
socket.close();
}
}
TCP 文件下载
客户端发送要获取的文件名,服务端根据文件名发送文件
服务端:
public class TCPFileUploadServerHW03 {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务端在监听 8888 端口");
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
byte[] buf = new byte[1024];
int len = 0;
String downloadName = "";
while ((len = inputStream.read(buf)) != -1) {
downloadName += new String(buf, 0, len);
}
System.out.println("客户端请求下载的文件名:" + downloadName);
String resFileName = downloadName.equals("高山流水") ? "src\\高山流水.mp3" : "src\\无名.mp3";
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(resFileName));
byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(accept.getOutputStream());
bufferedOutputStream.write(bytes);
accept.shutdownOutput();
bufferedOutputStream.close();
inputStream.close();
bufferedInputStream.close();
accept.close();
serverSocket.close();
}
}
客户端:
public class TCPFileUploadClientHW03 {
public static void main(String[] args) throws Exception {
Socket socket = new Socket(InetAddress.getLocalHost(), 8888);
System.out.println("输出要下载的文件名:");
Scanner scanner = new Scanner(System.in);
String msg = scanner.next();
OutputStream outputStream = socket.getOutputStream();
outputStream.write(msg.getBytes());
socket.shutdownOutput();
BufferedInputStream bufferedInputStream = new BufferedInputStream(socket.getInputStream());
byte[] bytes = StreamUtils.streamToByteArray(bufferedInputStream);
String desFilePath = "e:\\" + msg + ".mp3";
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(desFilePath));
bufferedOutputStream.write(bytes);
System.out.println("客户端成功保存!");
bufferedInputStream.close();
bufferedOutputStream.close();
outputStream.close();
socket.close();
}
}
|