网络编程

image-20231008132702602





三要素

  • IP:设备在网络中的地址,是唯一的标识
  • 端口号:应用程序在设备中唯一的标识。
  • 协议:数据在网络中传输的规则 常见的协议有UDP、TCP、http、https、ftp

image-20231008132902962



IP

  • IPv4:2^32
  • IPv6:2^128

image-20231008133224069

image-20231008133357121

image-20231008133336185


  • 回环地址:127.0.0.1 == 》 本机



端口

网络的通信,本质上是两个应用程序的通信。如果说IP地址可以唯一标识网络中的设备,那么端口号就可以唯一标识设备中的应用程序了。也就是应用程序的标识

image-20231008135557207



协议

计算机网络中,连接和通信的规则被称为网络通信协议

image-20231008135709378

image-20231008135810061


image-20231008135949466






InetAddress

方法 描述
static InetAddress getByName(String hast) 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
String getHostName() 获取此iP地址的主机名
String getHostAddress() 返回文本显示中的IP地址字符串
//IP对象--主机名/host  -- LAPTOP-JFOBLQKV/192.168.238.1
InetAddress name = InetAddress.getByName("LAPTOP-JFOBLQKV");
//获取主机名
String hostName = name.getHostName();
//获取host
String hostAddress = name.getHostAddress();





UDP通信

  • 面向无连接

发送数据

1、创建DatagramSocket对象

2、打包数据

3、发送数据

4、释放

/**
* 1.创建DatagramSocket对象(快递公司)
* 细节:
* 绑定端口,以后我们就是通过这个端口往外发送
* 空参:所有可用的端口中随机一个进行使用
* 有参:指定端口号进行绑定
*/
DatagramSocket datagramSocket = new DatagramSocket();

//2.打包数据
String str = "辰学UDP";
byte[] bytes = str.getBytes();
InetAddress byAddress = InetAddress.getByName("127.0.0.1");//目标
int port = 10086;//目标端口
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, byAddress, port);

//3.发送数据
datagramSocket.send(datagramPacket);

//4.释放资源
datagramSocket.close();

接收数据

1、创建DatagramSocket对象

2、打包数据

3、发送数据

4、释放

/**
* 1.创建DatagramSocket对象(快递公司)
* 细节:
* 在接收的时候,一定要绑定端口
* 而且绑定的端口一定要跟发送的端口保持一致
*/
DatagramSocket datagramSocket = new DatagramSocket(10086);

//2.接收数据
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
//该方法是阻塞的
//程序执行到这一步的时候,会在这里死等
//等发送端发送消息
datagramSocket.receive(datagramPacket);

//3.解析数据
byte[] data = datagramPacket.getData();
System.out.println("接收的数据:"+new String(data,0,datagramPacket.getLength()));
InetAddress address = datagramPacket.getAddress(); //发送方地址
int port = datagramPacket.getPort(); //发送方端口


简易聊天室

  • 发送
DatagramSocket datagramSocket = new DatagramSocket();

Scanner scanner = new Scanner(System.in);

while (true){
System.out.print("输入消息:");
String str = scanner.next();
byte[] bytes = str.getBytes();
InetAddress name = InetAddress.getByName("127.0.0.1");
int host = 10089;
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length,name,host);
datagramSocket.send(datagramPacket);
if (str.equals("886")){
break;
}
}

datagramSocket.close();


  • 接收
DatagramSocket datagramSocket = new DatagramSocket(10089);

byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);

while (true){
datagramSocket.receive(datagramPacket);
byte[] data = datagramPacket.getData();
System.out.println("接收到的数据:"+new String(data,0,datagramPacket.getLength()));
if (new String(data,0,datagramPacket.getLength()).equals("886")){
break;
}
}

datagramSocket.close();




三种通信方式

image-20231008144610749



  • 组播
//发送端

// DatagramSocket对象 改为 MulticastSocket对象
MulticastSocket multicastSocket = new MulticastSocket();

InetAddress byAddress = InetAddress.getByName("127.0.0.1"); //目标写为组播地址
//接收端
// DatagramSocket对象 改为 MulticastSocket对象
MulticastSocket multicastSocket = new MulticastSocket(端口);

//2.将本地添加到组播地址这一组中
InetAddress name = InetAddress.getByName("127.0.0.1");
datagramSocket.joinGroup(name);


  • 广播:把目标地址改为:255.255.255.255 ==> 局域网全部都可接收到数据





TCP通信

  • 服务端一开始等待连接,当客户端连接上后断开连接,服务端也会自动停止

image-20231008145728592

image-20231008145845265



  • 发送端
/**
* //1.创建Socket对象
* 细节:在创建对象的同时会连接服务端
* 如果连接不上,代码会报错
*/
Socket socket = new Socket("127.0.0.1", 1112);


//2.可以从连接通道中获取输出流
PrintStream printStream = new PrintStream(socket.getOutputStream(),true, "UTF-8");
//写出
printStream.printf("你好");

//3.释放
socket.close();


  • 接收端
//1.创建对象ServerSocker
ServerSocket serverSocket = new ServerSocket(1112);

//2.监听客户瑞的链接
Socket accept = serverSocket.accept();

//3.从连接通道中获取输入流读取数据
InputStream inputStream = accept.getInputStream();
//转换流
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

int read;
while ((read=inputStreamReader.read())!=-1){
System.out.println((char) read);
}

//4.关闭
serverSocket.close();


三次握手

image-20231008152313958


四次挥手

image-20231008152422271






TCP练习

1、

image-20231008154335720

//---------------------------------发送端
Socket socket = new Socket("127.0.0.1", 1201);
OutputStream outputStream = socket.getOutputStream();
Scanner scanner = new Scanner(System.in);
while (true){
String str = scanner.next();
outputStream.write(str.getBytes());
if (str.equals("886")){
break;
}
}
socket.close();


//---------------------------------接收端
ServerSocket serverSocket = new ServerSocket(1201);
Socket accept = serverSocket.accept();
InputStream inputStream = accept.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
int read;
while ((read=inputStreamReader.read())!=-1){
System.out.println((char) read);
}
serverSocket.close();


2、image-20231008155937027

  • 客户端
Socket socket = new Socket("127.0.0.1", 1202);


//发送
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好!".getBytes());

//写完使用结束标记
socket.shutdownOutput();

InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
//接收
int read;
while ((read=inputStreamReader.read())!=-1){
System.out.println((char) read);
}

socket.close();

  • 服务端
ServerSocket serverSocket = new ServerSocket(1202);

Socket accept = serverSocket.accept();

InputStream inputStream = accept.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

//读取
int read;
while ((read=inputStreamReader.read())!=-1){
System.out.println((char) read);
}

//回写
OutputStream outputStream = accept.getOutputStream();
outputStream.write("你也好呀!".getBytes());

accept.close();
serverSocket.close();


3、

image-20231008160054488

  • 客户端
Socket socket = new Socket("127.0.0.1", 1203);

//读取本地文件
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("D:\\1.JavaRoute\\Java\\TCP\\A\\cc.jpg"));

BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socket.getOutputStream());

//写出
int read;
byte[] bytes = new byte[1024];
while ((read=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,read);
}

//写出结束
socket.shutdownOutput();

//读入
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String s = bufferedReader.readLine();
System.out.println(s);


socket.close();

  • 服务端
ServerSocket serverSocket = new ServerSocket(1203);

Socket accept = serverSocket.accept();

//读取数据并保存到本地
BufferedInputStream bufferedInputStream = new BufferedInputStream(accept.getInputStream());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\1.JavaRoute\\Java\\TCP\\B\\cc.jpg"));

//读入
byte[] bytes = new byte[1024];
int read;
while ((read=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,read);
}

//回写数据
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bufferedWriter.write("上传成功");
bufferedWriter.newLine();
bufferedWriter.flush();


accept.close();
serverSocket.close();
  • 服务端使用线程池方案
public class ThreadDemo3 implements Runnable{
private Socket accept;
public ThreadDemo3(Socket socket) {
this.accept = socket;
}
@Override
public void run() {
try {
String replace = UUID.randomUUID().toString().replace("-", "");

BufferedInputStream bufferedInputStream = new BufferedInputStream(accept.getInputStream());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("D:\\1.JavaRoute\\Java\\TCP\\B\\"+replace+".jpg"));

int read;
byte[] bytes = new byte[1024];
while ((read=bufferedInputStream.read(bytes))!=-1){
bufferedOutputStream.write(bytes,0,read);
}

//回传
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream()));
bufferedWriter.write("上传成功");
bufferedWriter.newLine();
bufferedWriter.flush();

} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (accept!=null){
try {
accept.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
ServerSocket serverSocket = new ServerSocket(1203);

ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2,
5,
2,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);

while (true){
Socket accept = serverSocket.accept();
//线程
//new Thread(new ThreadDemo3(accept)).start();
//线程池
threadPoolExecutor.submit(new ThreadDemo3(accept));
}