网络编程
一、网络编程的概述
1.什么是网络编程
在网络"通信协议"下,实现"网络"互连的不同计算机上运行的"程序"间可以进行"数据交换"
//飞秋 就相当于可以实现网络间的数据交换
二、网络编程三要素
1.IP地址
*概念:"设备"在网络中的唯一标识
//只要是带网口的都可以称为设备
*分类
IPV4 和 IPV6
*常用命令
ipconfig:查看本机的IP地址 //192.168.0.2
ping + IPV地址 :查看本机和指定IP地址设备之间是否连通
ping 192.168.0.2
*特殊的IP地址 //掌握
127.0.0.1 : 代表的是本机的ip地址
2.端口号
*概念:应用程序在计算机中的唯一标识
*端口号的取值范围:
0-65535 但是0-1023我们不能使用,因为已经被知名网络占用 我们能用的1024-65535
*注意事项:
一个端口号只能绑定一个应用程序,如果强行的绑定多个,就会报错。第一个绑定的正常使用,第二个及其后面的会报错
2.协议
*概念:数据在网络中的传输的一种规则
*分类:
TCP 、 UDP
*TCP协议和UDP协议的区别? //面试题
UDP:
面向无连接(广播和电台)
数据不安全、速度快
数据大小有限制,一次最多64K
应用场景:视频会议
TCP:
面向连接(三次握手)
数据安全、速度慢
数据大小没有限制
应用场景:上传文件、迅雷下载、浏览网页
三、InetAddress类 //只要会创建对象即可
1.作用:用来表示我们生活中IP地址的
2.相关的方法
(1)static InetAddress getByName(String host)确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址//掌握
//参数:host既可以是计算机的名称 也可以是计算机的IP地址
代码举例:
InetAddress byName = InetAddress.getByName("192.168.0.2");
(2)String getHostName() 获取此IP地址的主机名
(3)String getHostAddress() 返回文本显示中的IP地址字符串
四、UDP通信
//注意:
(1)先关闭防火墙
选择控制面板------ Windows Defender 防火墙 --------- 启动或关闭Windows Defender 防火墙 ---- 两个都选择 关闭 Windows Defender 防火墙
(2)保证IP地址和端口号不能冲突
(3)一定要先运行接收程序,再运行发送程序
1.UDP发送数据
(1)步骤:
*创建发送端的Socket对象(DatagramSocket)
*创建数据,并把数据打包调用DatagramSocket对象的方法发送数据
*关闭发送端
代码实现:
public class Sender {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
byte[] bytes = "xxxx".getBytes();
DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.0.2"),12306);
ds.send(dp);
ds.close();
}
}
(2)类和方法
//构造方法
DatagramSocket() 创建数据报套接字并将其绑定到本机地址上的任何可用端口
DatagramPacket(byte[] buf,int len,InetAddress add,int port)创建数据包,发送长度为len的数据包到指定主机的指定端口
//方法
void send(DatagramPacket p) 发送数据报包
void close() 关闭数据报套接字
2.UDP接收数据
(1)步骤
创建接收端的Socket对象(DatagramSocket)
创建一个数据包,用于接收数据
调用DatagramSocket对象的方法接收数据
解析数据包,并把数据在控制台显示
关闭接收端
代码实现:
public class Receiver {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(12306);
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,1024);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
ds.close();
}
}
(2)相关的类和方法
构造方法:
DatagramPacket(byte[] buf, int len) 创建一个DatagramPacket用于接收长度为len的数据包
byte[] getData() 返回数据缓冲区
int getLength() 返回要发送的数据的长度或接收的数据的长度
3.UDP发送和接收数据的小结
发送端从哪个端口发送出数据对于我们接收端没有影响;只要保证包裹上的IP地址和端口号能找到接收端即可
4.UDP循环接收和发送数据案例
public class Sender {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket();
Scanner sc = new Scanner(System.in);
String str;
while ((str=sc.nextLine())!=null){
if ("886".equals(str)){
break;
}
byte[] bytes = str.getBytes();
DatagramPacket dp = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.0.2"),10010);
ds.send(dp);
}
ds.close();
}
}
------------------------------------------------------------------------------------------------------------------------------------
public class Receiver {
public static void main(String[] args) throws IOException {
DatagramSocket ds = new DatagramSocket(10010);
while (true){
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes,1024);
ds.receive(dp);
System.out.println(new String(dp.getData(),0,dp.getLength()));
}
}
}
五、TCP发送和接收数据
1.TCP发送数据
//构造方法
Socket(String host, int port) 创建流套接字并将其连接到指定主机上的指定端口号
//方法
InputStream getInputStream() 返回此套接字的输入流
OutputStream getOutputStream() 返回此套接字的输出流
代码实现:
public class TCPSender {
public static void main(String[] args) throws IOException {
Socket s1 = new Socket("192.168.0.2",10000);
OutputStream outputStream = s1.getOutputStream();
outputStream.write("xxxx".getBytes());
s1.close();
}
}
2.TCP接收数据
//构造方法
ServerSocket(int port) 创建绑定到指定端口的服务器套接字
//方法
Socket accept() 监听要连接到此的套接字并接受它
代码实现:
public class TCPReceiver {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(10000);
Socket accept = ss.accept();
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes,0,len));
ss.close();
}
}
六、案例
1.服务器给出反馈的案例
public class Sender {
public static void main(String[] args) throws IOException {
Socket s1 = new Socket("192.168.0.2",12356);
//给服务器端发送数据
OutputStream outputStream = s1.getOutputStream();
outputStream.write("一支穿云箭".getBytes());
//读取服务器给出的反馈
InputStream inputStream = s1.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes,0,len));
s1.close();
}
}
-----------------------------------------------------------------------
public class Receiver {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(12356);
Socket accept = ss.accept();
//读取发送端的数据
InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes,0,len));
//给出反馈的代码
OutputStream outputStream = accept.getOutputStream();
outputStream.write("漂亮妹纸来相见".getBytes());
ss.close();
}
}
七、shutdownOutput()方法 //了解
1.这个方法是哪个类的方法
Socket类的方法
2.作用
作为一个写数据的结束标记
3.应用场景
发送端循环写数据,并且需要接收服务端反馈
八、怎么解决文件重名问题(保证唯一的思想) //掌握
1.非多线程环境
*第一种:使用当前的时间毫秒值
//long timeMillis = System.currentTimeMillis();
*第二种:使用UUID
String string = UUID.randomUUID().toString().replace("-","");
2.多线程环境//(集群)
*使用UUID
String string = UUID.randomUUID().toString().replace("-","");