1. 网络编程入门

1.1 网络编程概述

  

  

1.2 网络编程三要素

  

1.3 IP地址

  

在命令提示符中使用

  
1.4 InetAddress的使用

  
代码示例:

public class InetAddressDemo {
// InetAddress
// 此类表示Internet协议(IP) 地址
public static void main(String[] args) throws UnknownHostException {
// public static InetAddress getByName (String host):
// 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址,推荐是使用IP地址
//InetAddress address = InetAddress.getByName("WxW");
InetAddress address = InetAddress.getByName("192.168.0.105"); // public String getHostName ():获取此IP地址的主机名
String hostName = address.getHostName();
System.out.println(hostName); // public String getHostAddress (): 返回文本显示中的IP地址字符串
String hostAddress = address.getHostAddress();
System.out.println(hostAddress);
}
}

运行结果:

  

代码示例:

public class InetAddressTest {
public static void main(String[] args) throws UnknownHostException {
System.out.println(InetAddress.getLocalHost());//LAPTOP-VEKHRDDR/192.168.240.1
System.out.println(InetAddress.getLocalHost().getHostName());//LAPTOP-VEKHRDDR
System.out.println(InetAddress.getLocalHost().getHostAddress());//192.168.240.1
System.out.println(InetAddress.getByName("192.168.3.11"));//输出:/192.168.3.11
System.out.println(InetAddress.getByName("192.168.3.11").getHostName());//LAPTOP-VEKHRDDR
System.out.println(InetAddress.getByName("192.168.3.11").getHostAddress());//192.168.3.11
System.out.println(InetAddress.getByName("LAPTOP-VEKHRDDR"));//LAPTOP-VEKHRDDR/192.168.240.1
System.out.println(InetAddress.getByName("LAPTOP-VEKHRDDR").getHostName());//LAPTOP-VEKHRDDR
System.out.println(InetAddress.getByName("LAPTOP-VEKHRDDR").getHostAddress());//192.168.240.1
}
}

运行结果:

  

1.5 端口

 

1.6 协议

  

   

三次握手

  

 

2. UDP通信程序

2.1 UDP通信原理

  

2.2 UDP发送数据

  

代码示例:

创建发送端

public class SendDemo {
public static void main(String[] args) throws IOException {
// 1:创建发送端的Socket对象(DatagramSocket)
// DatagramSocket ()构造数据报套接字并将其绑定到本地主机上的任何可用端口
DatagramSocket ds = new DatagramSocket(); // 2:创建数据,并把数据打包
// DatagramPacket (byte[] buf, int Length, InetAddress address, int port)
// 构造一个数据包,发送长度为length的数据 包到指定主机上的指定端口号。
byte[] bys = "hello,udp,我来了".getBytes();
int length = bys.length;
InetAddress destAddress = InetAddress.getByName("192.168.0.105");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys, length, destAddress, port); // 上面的步骤也可以写成这样
// DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("192.168.0.105"), 10086); // 3:调用DatagramSocket对象的方法发送数据
// void send (DatagramPacket p)从此套接字发送数据报包
ds.send(dp); // 4:关闭发送端
ds.close(); }
}

运行结果:
运行后并没有输出结果,因为还没有写接收端

2.3 UDP接收数据

  
代码示例:

创建接受端public class ReceiveDemo {    public static void main(String[] args) throws IOException {

// 1:创建接收端的Socket对象(DatagramSocket )
// DatagramSocket (int port)构造数据报套接字并将其绑定到本地主机上的指定端口
DatagramSocket ds = new DatagramSocket(10086); // 2:创建一个数据包,用于接收数据
// DatagramPacket (byte[] buf, int length) 构造一个 DatagramPacket用于 接收长度为Length数据包
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length); // 3:调用DatagramSocket对象的方法接收数据
ds.receive(dp); // 4:解析数据包,并把数据在控制台显示
// byte[] getData() 返回数据缓仲区
byte[] datas = dp.getData();
// int getLength () 返回要发送的数据的长度或接收到的数据的长度
int len = dp.getLength();
String dataString = new String(datas, 0, len); // 这样写是为了让输出的数据正好而不多余。
System.out.println("数据是:" + dataString); // 上面的步骤也可以这样写
// System.out.println("数据是:" + new String(dp.getData(), 0, dp.getLength()));
    
     
String ip = dp.getAddress().getHostAddress();
     System.out.println("收到"+ip+"发来的消息");
// 5:关闭接收端
ds.close(); }
}

运行结果:
运行时要先运行接收端再运行发送端,这样就就可以在接收端的控制台上看见接收到的数据了。

  
2.4 UDP通信程序练习

  
代码示例:

UDP发送端

/*
UDP发送数据:
数据来自于键盘录入,直到输入的数据是886,发送数据结束
*/
public class SendDemo {
public static void main(String[] args) throws IOException {
// 创建发送端的Socket对象(DatagramSocket )
DatagramSocket ds = new DatagramSocket(); // 自己封装键盘录入数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
// 输入的数据的886,发送数据接收
if ("886".equals(line)) {
break;
} // 创建数据,并把数据打包
byte[] bys = line.getBytes();
DatagramPacket dp = new DatagramPacket(bys, bys.length, InetAddress.getByName("192.168.0.105"), 12345); // 调用DatagramSocket对象发送程序
ds.send(dp);
}
// 关闭发送端
ds.close(); }

UDP接收端

/*
UDP接收数据:
因为接收端不知道发送端什么时候停止发送,故采用死循环接收
*/
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
// 创建接收端的Socket对象(DatagramSocket)
DatagramSocket ds = new DatagramSocket(12345); while (true) {
// 创建一个数据包,用于接收数据
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length); // 调用DatagramSocket对象的方法接收数据
ds.receive(dp);
       String data = new String(dp.getData(), 0, dp.getLength());
       // 解析数据包,并把数据在控制台显示 
       System.out.println("数据是:" + data);
    }

// 因为是采用死循环所以不需要关闭接收端
}
}

运行结果:

  

  

输入886结束接收

  

还可以开启多个发送数据窗口,每个窗口都可以发送数据,互不影响。

3. TCP通信程序

3.1 TCP通信原理

  

3.2 TCP发送数据

  
代码示例:

//TCP发送数据
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 1:创建客户端的Socket对象(Socket)
// Socket (InetAddress address, int port)创建流套接字并将其连接到指定IP地址的指定端口号
// Socket s = new Socket(InetAddress.getByName("192.168.0.105"), 1000);
// Socket (String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
Socket s = new Socket("192.168.0.105", 1000);// 这两个方法做的是同一件事 // 2:获取输出流,写数据
// OutputStream getOutputStream () 返回此套接字的输出流
OutputStream os = s.getOutputStream();
os.write("Hello,tcp,我来了".getBytes()); // 3:释放资源
s.close(); }
}

3.3 TCP接收数据

  
代码示例:

//TCP接收数据
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 1:创建服务器端的Socket对象(ServerSocket)
// ServerSocket (int port)创建绑定到指定端口的服务器套接字
ServerSocket ss = new ServerSocket(10000); // Socket accept() 侦听要连接到此套接字并接受它
Socket s = ss.accept(); // 2:获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;
while ((len = is.read(bys)) != -1) {
System.out.println("数据是:" + new String(bys, 0, len));
} // 3:释放资源
ss.close();
}
}

运行结果:
先开启接收端再开启发送端

  
3.4 TCP通信程序练习

3.4.1 练习1:发送数据接收反馈,接受数据发出反馈

  
代码示例:

创建客户端:

/*
* 客户端:发送数据,接收服务器反馈
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端的Socket对象(Socket)
Socket s = new Socket(" ", 1000); // 获取输出流,写数据
OutputStream os = s.getOutputStream();
os.write("hello,tcp,我来了".getBytes()); // 接收服务器反馈
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("客户端:" + data); // 释放资源
s.close(); }
}

创建服务器端:

/*
* 服务器:接收数据,给出反馈
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器端的Socket对象(ServerSocket)
ServerSocket ss = new ServerSocket(1000); // 监听客户端连接,返回一个Socket对象
Socket s = ss.accept(); // 获取输入流,读数据,并把数据显示在控制台
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys);
String data = new String(bys, 0, len);
System.out.println("服务器:" + data); // 给出反馈
OutputStream os = s.getOutputStream();
os.write("数据已收到".getBytes()); // 释放资源
ss.close(); }
}

运行结果:
先打开服务器,然后等待客户端连接。

  

  

3.4.2 练习2:用键盘录入数据

  
代码示例:

创建客户端:

/*
* 客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
*/
public class ClientDemo { public static void main(String[] args) throws IOException {
// 创建客户点Socket对象
Socket s = new Socket("192.168.0.105", 10000); // 数据来自于键盘录入,直到输入的数据是886,发送数据结束
// 使用自己包装的键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 封装输出流对象,将输出流封装成缓存流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line;
while ((line = br.readLine()) != null) { if ("886".equals(line)) {
break;
} // 获取输出流对象
// OutputStream os = s.getOutputStream();
// os.write(line.getBytes());
bw.write(line);
bw.newLine();
bw.flush();
}
// 释放资源
s.close();
}
}

创建服务器端:

/*
* 服务器:接收到的数据在控制台输出
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务器Socket对象
ServerSocket ss = new ServerSocket(10000); // 监听客户端的连接,返回一个对应的Socket对象
Socket s = ss.accept(); // 获取输入流,将输出流封装成缓存流
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
// 释放资源
ss.close();
}
}

运行结果:
先运行服务器端再运行客户端,在客户端输入数据发送到服务器端。

  

  

  

3.4.3 练习3:将键盘录入的数据写入文本文件

  
代码示例:

创建客户端:
客户端和练习2是一样的

/*
* 客户端:数据来自于键盘录入,直到输入的数据是886,发送数据结束
*/
public class ClientDemo { public static void main(String[] args) throws IOException {
// 创建客户点Socket对象
Socket s = new Socket("192.168.0.105", 10000); // 数据来自于键盘录入,直到输入的数据是886,发送数据结束
// 使用自己包装的键盘录入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 封装输出流对象
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line;
while ((line = br.readLine()) != null) { if ("886".equals(line)) {
break;
} // 获取输出流对象
// OutputStream os = s.getOutputStream();
// os.write(line.getBytes());
bw.write(line);
bw.newLine();
bw.flush();
}
// 释放资源
s.close();
}
}

创建服务端:

/*
* 服务器:接收到的数据写入文本文件
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务端Socket对象
ServerSocket ss = new ServerSocket(10000); // 监听客户端,返回一个对应的Socket对象
Socket s = ss.accept(); // 接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); // 把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("s.text"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 释放资源
bw.close();
ss.close(); }
}

运行结果:
先运行服务器再运行客户端,再客户端写数据传入服务器再写入文本文件。

  

  

3.4.4 练习4:数据来自文本,发送到服务器再写入文本(上传接收)

  
代码示例:

被复制文件是练习3的s.text
创建客户端:

/*
* 客户端:数据来自于文本文件
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.0.105", 10000); // 封装文本文件的数据
BufferedReader br = new BufferedReader(new FileReader("s.text")); // 封装输出流写数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
} // 释放资源
br.close();
s.close(); }
}

创建服务器:
服务器和练习3是一样的

/*
* 服务器:接收到的数据写入文本文件
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务端Socket对象
ServerSocket ss = new ServerSocket(10000); // 监听客户端,返回一个对应的Socket对象
Socket s = ss.accept(); // 接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); // 把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.text"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
}
// 释放资源
bw.close();
ss.close(); }
}

运行结果:
先运行服务器端再运行客户端。

  
3.4.5 练习5:在练习4的基础上加上服务器反馈

  

按照常规的方法会出现问题

  
代码示例:

接收服务器的反馈最重要的是在客户端加入结束标签shutdownOutput(),这样才能让服务器端知道你已经结束输出数据了。

创建客户端:

/*
* 客户端:数据来自于文本文件
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.0.105", 10000); // 封装文本文件的数据
BufferedReader br = new BufferedReader(new FileReader("s.text")); // 封装输出流写数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
} // 定义结束标签
// void shutdownOutput() 禁用此套接字的输出流。
s.shutdownOutput(); // 接收反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = brClient.readLine();
System.out.println("服务器的反馈:" + data); // 释放资源
br.close();
s.close();
}
}

创建服务端:

/*
* 服务器:接收到的数据写入文本文件
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务端Socket对象
ServerSocket ss = new ServerSocket(10000); // 监听客户端,返回一个对应的Socket对象
Socket s = ss.accept(); // 接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); // 把数据写入文本文件
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.text"));
String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
} // 给出反馈
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功!");
bwServer.newLine();
bwServer.flush(); // 释放资源
bw.close();
ss.close();
}
}

运行结果:

  
3.4.6 练习6:利用多线程使服务器接收多个客户端的文件

  
代码示例:

创建客户端类: 

/*
* 客户端:数据来自于文本文件
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建客户端Socket对象
Socket s = new Socket("192.168.0.105", 10000); // 封装文本文件的数据
BufferedReader br = new BufferedReader(new FileReader("s.text")); // 封装输出流写数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
} // 定义结束标签
// void shutdownOutput() 禁用此套接字的输出流。
s.shutdownOutput(); // 接收反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));
String data = brClient.readLine();
System.out.println("服务器的反馈:" + data); // 释放资源
br.close();
s.close();
}
}

创建服务器类:

/*
* 服务器:接收到的数据写入文本文件,给出反馈,代码用线程进行封装,为每一个客户端开启一个线程
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建服务端Socket对象
ServerSocket ss = new ServerSocket(10000); while (true) {
// 监听客户端,返回一个对应的Socket对象
Socket s = ss.accept();
// 为每一个客户端开启一个线程
new Thread(new ServerTherad(s)).start();
}
}
}

创建线程类:

public class ServerTherad implements Runnable {

    private Socket s;

    public ServerTherad(Socket s) {
this.s = s;
} @Override
public void run() {
try {
// 接收数据
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); // 把数据写入文本文件
// 解决命名冲突问题
int count = 0;
File file = new File("Copy[" + count + "].text");
while (file.exists()) {
count++;
file = new File("Copy[" + count + "].text");
}
BufferedWriter bw = new BufferedWriter(new FileWriter(file)); String line;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
} // 给出反馈
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bwServer.write("文件上传成功!");
bwServer.newLine();
bwServer.flush(); // 释放资源
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

运行结果:
先运行服务器再运行客户端,不过这次可以运行多次客户端,可以复制对个文件夹,而且不会重名。
第一次

  

  

第二次

  

  

Java基础00-网络编程29的更多相关文章

  1. 黑马程序员:Java基础总结----网络编程

    黑马程序员:Java基础总结 网络编程   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 网络编程 网络通讯要素 . IP地址 . 网络中设备的标识 . 不易记忆,可用 ...

  2. java基础知识——网络编程、IO流

    IO流 字节流:处理字节数据的流对象,计算机中最小数据单元就是字节.InputStream OutputStream 字符流:字符编码问题,将字节流和编码表封装成对象就是字符流.Reader Writ ...

  3. 黑马程序员——JAVA基础之网络编程

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 网络编程 网络模型:OSI参考模型和TCP/IP参考模型 网络通讯三要素: IP地址:InetA ...

  4. java基础篇---网络编程(TCP程序设计)

    TCP程序设计 在Java中使用Socket(即套接字)完成TCP程序的开发,使用此类可以方便的建立可靠地,双向的,持续的,点对点的通讯连接. 在Socket的程序开发中,服务器端使用serverSo ...

  5. java基础篇---网络编程(IP与URL)

    一:IP与InetAddress 在Java中支持网络通讯程序的开发,主要提供了两种通讯协议:TCP协议,UDP协议 可靠地连接传输,使用三方握手的方式完成通讯 不可靠的连接传输,传输的时候接受方不一 ...

  6. 【Java基础】网络编程

    网络编程 网络编程概述 网络编程的目的:直接或简洁地通过网络协议与其他计算机实现数据交换,进行通讯. 网络编程的两个主要问题: 如果准确地定位网络上一台或多台主机,并定位主机上的特定应用: 找到主机后 ...

  7. Java基础之网络编程

    网络编程:1.网络编程概述 (1)网络模型 OSI参考模型 TCP/IP参考模型 (2)网络通讯要素 IP地址 端口号 传输协议 (3)网络通讯前提: **找到对方IP **数据要发送到指定端口.为了 ...

  8. 黑马程序员——【Java基础】——网络编程

    ---------- android培训.java培训.期待与您交流! ---------- 一.网络模型概述 网络模型示意图: 说明: (1)数据的传输:在用户端,应用层的数据,经过层层封包,最后到 ...

  9. java基础:网络编程TCP,URL

    获取域名的两种方法: package com.lanqiao.java.test; import java.net.InetAddress;import java.net.UnknownHostExc ...

随机推荐

  1. AI框架精要:设计思想

    AI框架精要:设计思想 本文主要介绍飞桨paddle平台的底层设计思想,可以帮助用户理解飞桨paddle框架的运作过程,以便于在实际业务需求中,更好的完成模型代码编写与调试及飞桨paddle框架的二次 ...

  2. 如何打造高性能的 Go 缓存库

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/531 文中代码位置: https://github.com/devY ...

  3. Anno微服务Viper(控制面板) 支持在线部署

    1.Anno简介? Anno是一个微服务框架引擎.入门简单.安全.稳定.高可用.全平台可监控.依赖第三方框架少.可在线升级部署. 2.Viper简介 Viper 是一个基于Anno微服务引擎开发的Da ...

  4. Centos flock 防止脚本重复运行

    如果crontab设定任务每分钟执行一次,但执行的任务需要花费5分钟,这时系统会再执行导致两个相同的任务在执行.发生这种情况下可能会出现一些并发问题,严重时会导致出现脏数据性能瓶颈等恶性循环.为了防止 ...

  5. 带你认真了解一下Java分布式系统的基本特性

    一般,分布式系统需要支持以下特性: 资源共享 开放性 并发性 可伸缩性 容错性 透明性 下面分别讨论. 容易理解的 资源共享 一旦授权,可以访问环境中的任何资源 资源:包括硬件(e.g. printe ...

  6. Java语言实现二维码的生成

    众所周知,现在生活中二维码已经是无处不见.走在街道上,随处可见广告标语旁有二维码,手机上QQ,微信加个好友都能通过二维码的方式,我不知道是什么时候兴起的二维码浪潮,但是我知道,这在我小时候可是见不到的 ...

  7. excel VBA根据单元格内的逗号把内容拆分行

    Sub test1()    Dim h    Dim j As Integer    j = 0  '用于辅助循环的进行,可以在拆分行获取下一个需要拆分单元格的行号    'Application. ...

  8. 『动善时』JMeter基础 — 51、使用JMeter测试WebService接口

    目录 1.什么是WebService 2.WebService和SOAP的关系 3.什么是WSDL 4.测试WebService接口前的准备 (1)如何判断是WebService接口 (2)如何获取W ...

  9. Windows10 上Docker 安装运行Consul

    背景简介 Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面. 这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全服务网格. Consul需要数据平面并 ...

  10. flyway实现java 自动升级SQL脚本

    flyway实现java 自动升级SQL脚本 为什么要用Flyway 在日常开发中,我们经常会遇到下面的问题: 自己写的SQL忘了在所有环境执行: 别人写的SQL我们不能确定是否都在所有环境执行过了: ...