您的位置:首页 > 文旅 > 旅游 > Java_网络编程

Java_网络编程

2025/4/4 23:07:56 来源:https://blog.csdn.net/weixin_44738540/article/details/140240251  浏览:    关键词:Java_网络编程

网络通信的关键三要素

IP、端口号、协议

IP地址

IP地址(Internet Protocol):全程“互联网协议地址”,是分配给上网设备的唯一标志。

IP地址有两种形式:IPv4、IPv6

在这里插入图片描述

在这里插入图片描述

InetAddress

代表IP地址

InetAddress 的常用方法如下

名称说明
public static InetAdress getLocalHost()获取本机IP,会以一个inetAddress 的对象返回
public static InetAddress getByName(String host)根据ip地址或者域名,返回一个inetAddress对象
public String getHostName()获取该IP地址对象对应的主机名。
public String getHostAddress()获取该IP地址对象中的ip地址信息
public boolean isReachable(int timeout)在指定毫秒内,判断主机与该ip对应主机是否能够联通
import java.net.InetAddress;
import java.sql.SQLOutput;public class InetAddresstest {public static void main (String[] args )throws Exception{//1、获取本机IP地址对象InetAddress ip1 = InetAddress.getLocalHost();System.out.println(ip1.getHostName());System.out.println(ip1.getHostAddress());//2、获取指定IP或者域名的IP地址对象InetAddress ip2=InetAddress.getByName("www.baidu.com");System.out.println(ip2.getHostName());System.out.println(ip2.getHostAddress());System.out.println(ip2.isReachable(6000));}}

端口号

标记正在设备上运行的应用程序的,被规定为一个16位的二进制,范围是0~65535

分类

周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)

注册端口:1024~49151,分配给用户进程或某些应用程序。

动态端口:49151到65535,之所以被称为动态端口,是因为它一般不固定分配某种进程,而是动态分配。

注意:我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则会出错。

通信协议

网络上通信设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议。

开放式互联网络互联标准:OSI 网络参考模型

OSI网络参考模型:全球网络互联标准
TCP/IP网络模型:事实上的国际标准
在这里插入图片描述

传输层的两个通信协议

UDP(User Datagram Protocol):用户数据报协议;
TCP(Transmission Control Protocol) :传输控制协议

UDP

特点:无连接、不可靠通信

不事先建立连接,数据按照包发,一包数据含:自己的IP、程序端口、目的IP、程序端口和数据(限制在64KB内)
发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,是不可靠的。

TCP

特点:面向连接、可靠通信。
TCP的最终目的:要保证在不可靠的信道上实现可靠传输。
TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接。

在这里插入图片描述

在这里插入图片描述

UDP通信

特点:无连接、不可靠通信
不事先建立连接;发送端每次要把发送的数据(限制在64KB内)、接收端IP、等信息封装成一个数据包,发不出去就算了。
Java提供了一个Java.net.DatagramSocket类来实现UDP通信。

在这里插入图片描述

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.sql.SQLOutput;public class Server {public static void main(String[] args) throws Exception{//1、创建一个服务对象(创建一个接韭菜的人)注册端口DatagramSocket socket =new DatagramSocket(6666);//2、创建一个数据包对象,用于接受数据的(创建一个韭菜盘子)byte[] buffer = new byte[1024*64];DatagramPacket packet = new DatagramPacket(buffer, buffer.length);while (true) {//3、开始正式使用数据包来接受客户端发来的数据socket.receive(packet);//4、从字节数组中,把接收到的数据直接打印出来//接受多少就到处多少//获取本次数据包接受了多少数据。int len = packet.getLength();String rs= new String(buffer,0,len);System.out.println(rs);System.out.println(packet.getAddress().getHostAddress());System.out.println(packet.getPort());System.out.println("----------------");}}
}import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception{//1、创建客户端对象DatagramSocket socket = new DatagramSocket();//2、创建数据包对象封装要发出去的数据(创建一个韭菜盒子)//public DatagramPacket(byte buf[],int length,InetAddress address,int port)//InetAddress address,int port)//参数1:封装要发出去的数据。//参数2:发出去的数据大小(字节个数)//参数3:服务器额的IP地址//参数4:服务程序的端口Scanner sc= new Scanner(System.in);while (true) {System.out.println("请说:");String msg= sc.nextLine();if("exit".equals(msg)) {System.out.println("欢迎下次光临!推出成功!");socket.close();break;}byte[] bytes = msg.getBytes();DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),6666);//3、正式发送这个数据包的数据出去了socket.send(packet);}}
}

TCP通信

特点:面向连接、可靠通信

通信方面事先会采用”方式建立可靠连接“,实现端到端的通信;底层能保证数据成功传给服务器

java提供了一个Java.net.Socket类来实现TCP通信。


import java.io.DataInputStream;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLOutput;public class Server {public static void main(String[] args) throws Exception{//1、创建ServerSocket的对象,同时为服务端注册端口ServerSocket serverSocket = new ServerSocket(8888);//2、从serverSocket对象,调用accept方法,等待客户端的连接请求Socket socket = serverSocket.accept();//3、从socket通信管道中得到一个字节输入流InputStream is = socket.getInputStream();//4、把原始的字节输入流包装成数据输入流DataInputStream dis = new DataInputStream(is);//5、使用数据输入流读取客户端发过来的消息String rs=dis.readUTF();System.out.println(rs);//其实我们也可以获取客户端的IP地址System.out.println(socket.getRemoteSocketAddress());dis.close();socket.close();}
}import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;public class Client {public static void main(String[] args) throws Exception{//1、创建Socket对象,并同时请求与服务端程序的连接Socket socket= new Socket("127.0.0.1",8888);//2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。OutputStream os= socket.getOutputStream();//3、把低级字节输出流包装成数据输出流DataOutputStream dos = new DataOutputStream(os);//4.开始写数据出去了dos.writeUTF("在一起号码!");dos.close();socket.close();}
}

下面是一个简单的Java程序,用于实现多个客户端同时通信:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;public class MultiClientServer {private List<Socket> clients = new ArrayList<>();public static void main(String[] args) {MultiClientServer server = new MultiClientServer();server.start();}public void start() {try {ServerSocket serverSocket = new ServerSocket(9999);System.out.println("Server started");while (true) {Socket clientSocket = serverSocket.accept();clients.add(clientSocket);ClientHandler clientHandler = new ClientHandler(clientSocket);Thread clientThread = new Thread(clientHandler);clientThread.start();}} catch (Exception e) {e.printStackTrace();}}private class ClientHandler implements Runnable {private Socket clientSocket;private BufferedReader reader;private PrintWriter writer;public ClientHandler(Socket clientSocket) {this.clientSocket = clientSocket;try {reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));writer = new PrintWriter(clientSocket.getOutputStream(), true);} catch (Exception e) {e.printStackTrace();}}@Overridepublic void run() {try {String message;while ((message = reader.readLine()) != null) {System.out.println("Received message: " + message);// 向所有客户端发送消息for (Socket client : clients) {PrintWriter clientWriter = new PrintWriter(client.getOutputStream(), true);clientWriter.println(message);}}} catch (Exception e) {e.printStackTrace();}}}
}

这个程序创建了一个服务器端,可以同时处理多个客户端的连接。当一个客户端发送消息时,服务器会将该消息转发给所有连接的客户端。

运行这个程序后,可以使用多个客户端程序连接到服务器,并进行通信。每个客户端发送的消息都会被服务器广播给所有连接的客户端。

注意:这个程序是一个简单的示例,没有处理异常情况和并发安全性。在实际使用中,应该对异常进行处理并确保多个线程之间的安全访问。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com