zl程序教程

您现在的位置是:首页 >  后端

当前栏目

(服务器&客户端)网络通信是怎么实现的?7000字爆肝----原来java网络编程技术功不可没(多线程,URL,InetAddressm,TCP,UDP)集结

2023-09-11 14:19:58 时间

在这里插入图片描述

👨‍💻个人主页@元宇宙-秩沅

hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

本文由 秩沅 原创

收录于专栏 java

⭐java网络编程技术⭐



👨‍💻一,URL类


👨‍💻概念


👍1. 是java.net包中一个重要的类

👍2. 一个URL对象通常包含:协议,地址,资源 三部分

👍3. HTTP协议

在这里插入图片描述


👨‍💻二,InetAddress类


InetAddress类包括下面两个表示地址的方式描述
域名如:www.csdn.com
IP地址如:127.0.0.1
在这里插入图片描述

👍1.获取Internet上主机的地址

在这里插入图片描述

👍2.获取本地

在这里插入图片描述

👍3,输入域名可以对应推出IP地址,但输入IP地址不能得出域名,DNS正向解析无反向解析


👨‍💻三,套接字



👨‍💻概念


👍1.当两个程序需要通信时,它们可以通过使用Socket类 建立套接字对象,并连接在一起

👍2.端口号的范围在: 0~65535之间

在这里插入图片描述


👨‍💻套接字连接示意图


在这里插入图片描述


👨‍💻客户端套接字


👍1,客户端的程序使用 Socket类 建立负责连接到服务器的套接字对象

👍2.构造方法–参数为 服务器 的IP地址

在这里插入图片描述

👍3.和mysocket的相关方法

在这里插入图片描述


👨‍💻服务器端套接字


👍1.建立ServerSocket对象

作用连接客户端套接字对象 和 服务器端 一个套接字对象
特点ServerSocket对象不能重复创建,除非更换端口号

👍2.建立ServerSocket对象语句

在这里插入图片描述

👍3.具体是使用该对象的方法accept():来达到连接客户的套接字 和 服务器端 的套接字

在这里插入图片描述

👍4.所谓“接收”客户的套接字连接:

  • 就是 accept( )方法会返回 Socket对象 - 该对象和客户端的Socket对象是连接关系

👨‍💻客户端和服务器的连接关系


👍客户端Socket对象, 获得的 输入流 和 服务端Socket对象, 获得的 输出流 相互连接 ,反之亦然

在这里插入图片描述


👨‍💻三,多线程技术


👍1.为了防止堵塞线程,服务器端收到一个客户得套接字后,就应该启动一个专门为该客户服务线程

👍2.客户用Socket类构建了mySocket套接字对象之后,该对象需调用,connect()方法;
目的是和套接字进行连接;

在这里插入图片描述

👍3.为了使用connect()方法,要使用SocketAddress类 的子类 InetSocketAddress 创建一个对象,
InetSocketAddress的构造方法是:

在这里插入图片描述

👍4.具有多线程的服务器程序图

在这里插入图片描述
注意:开套接字要在try里面


👨‍💻四,UDP数据报–基于UDP协议



👨‍💻概述


👍UDP传递信息 更快但是不保证可靠性

👍什么时候使用 : 急切地发送消息的情况使用

👍一般不可靠


👨‍💻发送数据包


👍1.用DatagramPacket类将数据打包

既用该类创建一个对象,称为数据包

以下两个构造方法创建待发送的数据包。

DatagramPacket(byte datal ],int length, InetAddress address,int port)

使用第一个构造方法创建的数据包对象具有下列两个性质:

  • 含有data数组指定的数据。
  • ·该数据包将发送到地址是address、端口号是 port的主机上。称address是这个数据包的目标地址,port是它的目标端口。

DatagramPack(byte data[ ], int offset, int length, InetAddress address, int port)

  • 使用第二个构造方法创建的数据包对象含有数组 data 中从 offset开始的length个字该数据包将发送到地址是address、端口号是port的主机上。

例如:
byte data[]="生日快乐".getByte();
InetAddress address=InetAddress, getName(“www. china.com. cn”) ;
DatagramPacketdat_pachnewDatagramPacket(data, data. length, address,
2009);
注:对于用上述方法创建的用于发送的数据包,data pack 调用方法 public int getPo


👨‍💻接收数据包


👍1.用DatagramSocket的另一个构造方法DatagramSocket(int port)创建一个对象

  • 其中的参数必须和待接收的数据包的端口号相同。

例如,如果发送方发送的数据包的端口是5666,那么如下创建DatagramSocket对象:
DatagramSocket mail_in=new DatagramSocket(5666);

  • 然后对象mail_in使用方法receive(DatagramPacket pack)接受数据包。

用DatagramPack类的另外一个构造方法:
DatagramPack(byte data|l,int length)

  • 创建一个数据包,用于接收数据包,

例如:
byte data[]=new byte[100];
int length=90:
DatagramPacket pack=new DatagramPacket(data,length);
mail_in.receive(pack);
-该数据包pack将接收长度是length字节的数据放入data。


五,服务端和客户端的连接应用代码


👨‍💻👍

1.客户端类

Client.java
import java.io.*;
import java.net.*;
import java.util. *;
public class Client {
public static void main(String args[]){

Scanner scanner = new Scanner(System. in);
Socket mysocket= null;    //声明套接字对象
DataInputStream in=null;   // 输入流数据
DataOutputStream out=null; //  输出流数据
Thread readData;          //   线程
Read read=null;
try{ mysochcket = new Socket();
read = new Read();
readDatata = newad(read);
//负责读取信息的线程
System.out.print("输入服务器的IP:");
String IPg IP = scannextLine(); 
System.out.print("输入端口号:");
int port=anner.nextInt();
ort = scanne
if(mysocket.isConnected()){}
else{
InetAddress address=InetAddress.getByName(IP);
InetSocketAddress socketAddress = new InetSocketAddress
(address,port);
mysocket.connect(socketAddress);
in = new DataInputStream(mysocket. getInputStream());
out = new DataOutputStream(mysocket.getOutputStream());
read.setDataInputStream(in);
readData.start();
//启动负责读取信息的线程 ,随即run方法也会随着其一同运行
}
catch(Exception e){
System.out.println("服务器已断开""+e);
}
System.out.print("输入圆的半径(放弃请输入N):");
while(scanner.hasNext()){
ius=0;double radius=
try{
radius=s = scanner.nextD
}
catch(InputMismatchException exp){
System.exit(0);
}
try{
out.writeDouble(radius);
//向服务器发送信息
}
catch(Exception e){}
}
}
}

2.中介消息Read类

Read.java
import java.io.*;
public class Read implements Runnable{
DataInputStream in;
public void setDataInputStream(DataInputStream in){
this.in= in;
}
public void run() {
double result = 0;
while(true){
try{ result = in.readDouble();
//读取服务器发送来的信息
System.out.println("圆的面积:"+result)
System.out.print("输入圆的半径(放弃请输入N):");
}
catch(IOException e){
System.out.println("与服务器已断开"+e);
break;
}

3.服务器类

import java.io.*;
import java.net. *;
import java. util.*;
public class Server {
public static void main(String args[ ]) {
ServerSocket server = null;
ServerThread thread;
Socket you=null;
while(true){
try{ server = new ServerSocket(2010);
}
catch(I0Exception e1){
//ServerSocket 对象不能重复创建,除非更换端口号
System.out.println("正在监听");
}
tryl System,out.println(“等待客户呼叫");
you = server,accept();
System.out.println(*客户的地址:"*you.getInetAddress());
}
catch(I0Exception e){
System.out.println("正在等待客户");
{
if(you!=null){
new ServerThread(you).start();
//为每个客户启动一个专门的线程
    }
  }
 }class ServerThread extends Thread{
Socket socket;
DataOutputStream out = null;
DataInputStreamin=null;
String s=null;
ServerThread(Socket t) {
socket=t;
try { out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream( socket. getInputStream());
}
catch(IOException e){}
}
public void run() {
while(true){
try{double r= in.readDouble();
//堵塞状态,除非读取到信息
double area = Math. PI * r*r;
out.writeDouble(area);
}
catch(IOException e) {
System.out.println("客户离开");
return;
      }
     }
  }
}


👨‍💻博主专属私人入口莫点🤭


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!
在这里插入图片描述