您的位置:首页 > 理论基础 > 计算机网络

【Java】-- Java网络编程小记

2021-05-05 21:47 1256 查看

Java网络编程

1. 获取网络地址ip/domin

InetAddress 获取

package com.fengye.socket.ipaddress;

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
* @Description:
* @Author: huang
* @Date: 2021/5/5 11:30
*/
public class TestInetAddress {
public static void main(String[] args) throws UnknownHostException {
InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
InetAddress localhost = InetAddress.getByName("localhost");
InetAddress localHost = InetAddress.getLocalHost();
InetAddress deskTopName = InetAddress.getByName("DESKTOP-3POL04N");  // 本机用户名
InetAddress bdAddress = InetAddress.getByName("www.baidu.com");
byte[] address = new byte[]{(byte) 192, (byte) 168,5,2};
InetAddress byAddress = InetAddress.getByAddress(address);
System.out.println(inetAddress);  // /127.0.0.1
System.out.println(localhost);   // localhost/127.0.0.1
System.out.println(localHost);  // DESKTOP-3POL04N/192.168.1.4
System.out.println(deskTopName);  // DESKTOP-3POL04N/192.168.1.4
System.out.println(bdAddress);    // www.baidu.com/39.156.66.18
System.out.println(byAddress);    // /192.168.5.2

System.out.println(localhost.getAddress());
System.out.println(localhost.getCanonicalHostName());   // 获取规范名
System.out.println(localhost.getHostAddress());         // ip
System.out.println(localhost.getHostName());             // 域名 主机名
}
}

 

2.Port 端口

  • 计算机端口号用于区分不同的进程

  • 计算机端口按端口号可分为3大类:

(1)公认端口:从0到1023,它们紧密绑定于一些服务。通常这些端口的通讯明确表明了某种服务的协议。常用的有:http: 80 https: 443 ftp: 21 ssh: 22 telnet: 23

(2)注册端口:从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些 端口同样用于许多其它目的。常用的有:TomCat: 8080 MySql: 3306 Oracle:1506

(3)动态和私有端口:从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从 1024起分配动态端口。

 

  • 对于不同的传输层传输协议,在进行数据封装时包头信息不一样,即使UDP包和TCP包使用同一个端口,也不会导致端口冲突。

  • 查看端口命令

netstat -a #
netstat -ano|findstr "7024" #查看指定端口
tasklist|findstr "7024" # 查看指定端口进程

 

InetSocketAddress

package com.fengye.socket.socketaddress;

import java.net.InetSocketAddress;

/**
* @Description:
* @Author: huang
* @Date: 2021/5/5 11:42
*/
public class TestInetSocketAddress {
public static void main(String[] args) {
InetSocketAddress localhost = new InetSocketAddress("192.168.1.4", 8080); // ip/主机+创建端口对象
System.out.println(localhost.getAddress());  //  /192.168.1.4
System.out.println(localhost.getHostName());  //  DESKTOP-3POL04N
System.out.println(localhost.getPort()); // 获得端口号  8080
System.out.println(localhost.getHostString());  // DESKTOP-3POL04N
}
}

 

3.通信协议

传输层通信协议

  • TCP:面向连接

  • UDP:非面向连接

 

4.TCP编程实现

Java语言的基于套接字编程分为服务端编程和客户端编程,其通信模型如图所示:

 

4.1.TCP编程简单C/S通信示例

1、客户端Socket的工作过程包含以下四个基本的步骤:

创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务端的通信路线。若连接失败,则会出现异常。

打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用 getOutputStream()方法获得输出流,进行数据传输

按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入路线的信息),通过输出流将信息写入线程

/**
* @Description:
* @Author: huang
* @Date: 2021/5/5 11:56
*/
public class TestTcpClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8888);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好,我是机器人小爱,正在为你转接人工服务通信,建立连接中。。。".getBytes(StandardCharsets.UTF_8));
if (outputStream != null) {
outputStream.close();
}
if (socket != null) {
socket.close();
}
}
}

 

2、服务器(服务端)程序的工作过程包含以下四个基本的步骤:

调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端口 上。用于监听客户端的请求。

调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信 套接字对象。

调用该Socket类对象的 getOutputStream() 和 getInputStream ():获取输出 流和输入流,开始网络数据的发送和接收。

/**
* @Description:
* @Author: huang
* @Date: 2021/5/5 12:09
*/
public class TestTcpServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("连接建立中");
Socket clientSocket = serverSocket.accept();
System.out.println("与"+clientSocket.getInetAddress()+"成功建立连接");
InputStream inputStream = clientSocket.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len=0;
while ((len=inputStream.read(buffer))!=-1){
out.write(buffer,0,len);
System.out.println(out.toString());
}
if(out!=null)
out.close();
if (inputStream!=null)
inputStream.close();
if (clientSocket!=null)
clientSocket.close();
if (serverSocket!=null)
serverSocket.close();
}
}

 

4.2.TCP编程实现C/S文件传输

Server:

package com.fengye.socket.tcp;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
* @Descripti
56c
on: 服务端负责接收文件
* @Author: huang
* @Date: 2021/5/5 12:22
*/
public class TestTcpFileTransportServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(4396);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
byte[] bufferFile = new byte[1024];
int len;
File received = new File("E:\\Works
ad8
paces\\Java\\JavaSocket\\src\\com\\fengye\\socket\\tcp\\images\\test.png");
FileOutputStream output = new FileOutputStream(received);
while ((len=inputStream.read(bufferFile))!=-1){
output.write(bufferFile,0,len);
}
// 接受完毕,告知客户断开连接
OutputStream outputStream = socket.getOutputStream();
outputStream.write("接收成功".getBytes(StandardCharsets.UTF_8));
output.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}

 

Client:

package com.fengye.socket.tcp;

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

/**
* @Description: 客户端向服务端传送文件
* @Author: huang
* @Date: 2021/5/5 12:17
*/
public class TestTcpFileTransportClient {
public static void main(String[] args) throws IOException {
// 创建socket
Socket socket = new Socket("localhost",4396);
// 创建流
OutputStream outputStream = socket.getOutputStream();
// 读取文件
File file = new File("E:\\Workspaces\\Java\\JavaSocket\\src\\com\\fengye\\socket\\tcp\\images\\img.png");
byte[] buffer = new byte[1024];
// 文件输入流
FileInputStream fileInputStream = new FileInputStream(file);
// 写入流
int len;
while ((len=fileInputStream.read(buffer))!=-1){
outputStream.write(buffer);
}
// 文件传输结束,关闭输出
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
byte buffer2[] = new byte[20];
ByteArrayOutputStream msg = new ByteArrayOutputStream();
while ((len=inputStream.read(buffer2))!=-1){
msg.write(buffer2,0,len);
}
System.out.println(msg);
msg.close();
inputStream.close();
fileInputStream.close();
outputStream.close();
socket.close();
}
}

 

5.UDP 编程

1、类DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。

2、UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证 UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。

3、DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。

4、UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。如同发快递包裹一样。

 

UDP网络通信流程

1、DatagramSocket与DatagramPacket

2、建立发送端,接收端

3、建立数据包

4、调用Socket的发送、接收方法

5、关闭Socket

 

接收方:

package com.fengye.socket.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class TestUdpGet {
public static void main(String[] args) throws IOException {
//开放端口
DatagramSocket socket = new DatagramSocket(2200);
while (true<
56c
/span>){
//接收数据
byte[] buffer  = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);

socket.receive(packet);  //阻塞接收
System.out.println(packet.getAddress().getHostAddress());
String msg = new String(packet.getData(), 0, packet.getLength());
if (msg.equals("shutdown")){
System.out.println("Connection has been closed");
socket.close();
return;
}
System.out.println(msg);
}
}
}

 

发送方

package com.fengye.socket.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class TestUdpSend {
public static void main(String[] args) throws IOException {
//建立一个socket
DatagramSocket socket = new DatagramSocket(1111);
Scanner reader = new Scanner(System.in);
while (true){
String data = reader.nextLine();
byte[] msgBytes = data.getBytes(StandardCharsets.UTF_8);
InetAddress localhost = InetAddress.getByName("localhost");
DatagramPacket datagramPacket = new DatagramPacket(msgBytes, 0, msgBytes.length, localhost, 2200);
socket.send(datagramPacket);
if (data.equals("shutdown")){
System.out.println("Connection is closed ");
reader.close();
socket.close();
return;
}
}
}
}

 

多线程实现聊天功能

package com.fengye.socket.udp.threadchat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

/**
* @Description: 消息发送方线程
* @Author: huang
* @Date: 2021/5/5 13:14
*/
public class MsgSender implements Runnable{

private String destinationAddress;
private int destinationPort;

DatagramSocket socket = null;
BufferedReader reader = null;

public MsgSender(int sourcePort, int destinationPort, String destinationAddress) throws SocketException {
this.destinationAddress = destinationAddress;
this.destinationPort = destinationPort;
this.socket = new DatagramSocket(sourcePort);
this.reader = new BufferedReader(new InputStreamReader(System.in));
}

@Override
public void run() {
while (true){
try {
String data = reader.readLine();
byte[] dataByte = data.getBytes(StandardCharsets.UTF_8);
DatagramPacket packet = new DatagramPacket(dataByte,0,dataByte.length,
new InetSocketAddress(destinationAddress, destinationPort));
socket.send(packet);
if(data.equals("shutdown")){
reader.close();
socket.close();
return;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

 

package com.fengye.socket.udp.threadchat;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
* @Description: 消息接收方线程
* @Author: huang
* @Date: 2021/5/5 13:23
*/
public class MsgReceiver implements Runnable{
private int port;
private String msgSeeder;
DatagramSocket socket = null;
public MsgReceiver(int port, String msgSeeder) throws SocketException {
this.port = port;
this.msgSeeder = msgSeeder;
socket = new DatagramSocket(port);
}

@Override
public void run() {
while (true){
try {
byte[] msgBuffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(msgBuffer,0,msgBuffer.length);
socket.receive(packet);
byte[] data = packet.getData();
String msg = new String(data,0, packet.getLength());
if (msg.equals("shutdown")) {
socket.close();
return;
}
System.out.println(msgSeeder+": "+msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @Description: 发送目的端口和监听消息端口必须一致
* @Author: huang
* @Date: 2021/5/5 13:27
*/
public class TestClient01 {
public static void main(String[] args) throws SocketException {
new Thread(new MsgSender(1233,
8888,"localhost")).start();
new Thread(new MsgReceiver(8888,"T1客户端")).start();
}
}
public class TestClient02 {
public static void main(String[] args) throws SocketException {
new Thread(new MsgSender(1234,
8800,"localhost")).start();
new Thread(new MsgReceiver(8800,"T2客户端")).start();
}
}

 

6.URL 编程

url:统一资源定位符

格式:<协议>://<主机><端口>/<路径>

package com.fengye.socket.url;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class TestUrl {
public static void main(String[] args) throws IOException {
// 1.资源地址
URL url = new URL("http://music.163.com/song/media/outer/url?id=1403528956.mp3");
<
1044
span style="color: rgba(0, 128, 0, 1)">// 2.url解析
System.out.println(url.getProtocol()); // 协议
System.out.println(url.getHost()); // 主机
System.out.println(url.getPort()); // 端口
System.out.println(url.getPath());
System.out.println(url.getFile());
System.out.println(url.getQuery()); // 参数
System.out.println(url.getAuthority());
System.out.println(url.getContent()); // 内容
// 3.连接资源url
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream stream = urlConnection.getInputStream();
// 4. 文件输出流到 test.mp3
FileOutputStream outputStream = new FileOutputStream("test.mp3");
byte[] bytes = new byte[1024];
int len;
while ((len=stream.read(bytes))!=-1){
outputStream.write(bytes,0,len);
}
// 5.下载完毕关闭流和url连接
stream.close();
outputStream.close();
urlConnection.disconnect();
}
}

 

参考博文:

Java网络编程

本博客涉及示例代码均已上传至GitHub地址:

JavaSocket

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: