255.255.255.255 广播IP
TCP
如何通过TCP来进行网络数据传输呢?
TCP底层基于流的;
客户端:
Socket这个类实现了客户端套接字(也被称为“套接字”)。套接字是两台机器之间的通信的一个端点。
构造方法:
Socket()
创建一个连接的套接字,与socketimpl系统默认的类型。
Socket(InetAddress address, int port)
创建一个流套接字,并将其与指定的IP地址中的指定端口号连接起来。
方法:
void connect(SocketAddress endpoint)
将此套接字连接到服务器。
InputStream getInputStream()
返回此套接字的输入流。
OutputStream getOutputStream()
返回此套接字的输出流。
void shutdownInput() --读取完成
void shutdownOutput() --输出完成
服务器端
ServerSocket:这个类实现了服务器套接字。服务器套接字等待来自网络的请求。它基于该请求执行某些操作,然后可能向请求者返回结果。
构造方法:
ServerSocket(int port)
创建一个服务器套接字,绑定到指定的端口。
方法:
Socket accept() —接受客户端的连接请求,返回一个代表当前正在连接的客户端对象
TCP实现网络数据传输
客户端
1、创建客户端对象
2、发起连接服务器端的请求
3、获取一个输出流
4、写出数据
5、通知服务器端写出完成
6、关流
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* 此案例为tcp的客户端代码
*/
public class TCPClientDemo {
public static void main(String[] args) throws IOException {
//1、创建客户端对象 Socket
Socket socket = new Socket();
//2、发起连接服务器端的请求 connect
//需要一个参数指定服务器端的ip地址和端口号
socket.connect(new InetSocketAddress("127.0.0.1",8888));
//3、获取一个输出流
OutputStream out = socket.getOutputStream();
//4 写出数据
out.write("hello".getBytes());
//5 通知服务器已经写出完成
socket.shutdownOutput();
//6 关闭客户端
socket.close();
}
}
服务器端:
1、创建服务器端对象ServerSocket
2、接受客户端的请求accept-》socket
3、获取一个输入流
4、读取数据
5、通知客户端数据读取完成
6、关流
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 此案例为tcp的服务器端代码
*/
public class TCPServerDemo {
public static void main(String[] args) throws IOException {
//1、创建服务器端对象 ServerSocket
ServerSocket ss = new ServerSocket(8888);
//2、接受客户端的请求 accept -》Socket
//accept阻塞
Socket socket = ss.accept();
//3、获取一个输入流
InputStream in = socket.getInputStream();
//4、读取数据
byte[] bytes = new byte[1024];
int len;
while((len=in.read(bytes))!= -1){
//打印数据
System.out.println(new String(bytes,0,len));
}
//5、通知客户端数据读取完成
socket.shutdownInput();
//6 关闭流
ss.close();
}
}
练习
文件上传
客户端将本地的文件(C盘)上传至服务器端:
1、创建客户端对象
2、连接服务器端
3、输入流,读取本地文件
4、获取一个输出流
5、读取本地文件,一边发送给服务器端
6、通知服务器端文件发送完成
7、关闭所有流
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* 此案例为tcp的练习文件上传的客户端代码
*/
public class FileUploadClient {
public static void main(String[] args) throws IOException {
// 1、创建客户端对象
Socket socket = new Socket();
// 2、连接服务器端
socket.connect(new InetSocketAddress("127.0.0.1", 8899));
// 3、输入流,读取本地文件
FileInputStream in = new FileInputStream("c:\\jdk.CHM");
// 4、获取一个输出流
OutputStream out = socket.getOutputStream();
// 5、读取本地文件,一边发送给服务器端
byte[] bytes = new byte[1024];
int len;
while ((len = in.read(bytes)) != -1) {
//将一部分数据读取到了bytes数组中
//将bytes内容发送到服务器端
out.write(bytes, 0, len);
}
// 6、通知服务器端文件发送完成
socket.shutdownOutput();
//新增功能 获取服务器端的回复数据并打印
InputStream in1 = socket.getInputStream();
byte[] bytes1 = new byte[1024];
int len1;
while ((len1 = in1.read(bytes1))!=-1){
String msg = new String(bytes1,0,len1);
System.out.println(msg);
}
//通知服务器端数据读取完成
socket.shutdownInput();
// 7、关闭所有流
socket.close();
in.close();
}
}
服务器端接收客户端传输的文件存储(D盘):
1、创建服务器对象
2、接收客户端请求
3、获取一个输入流
4、准备一个输出流,将数据写出到D盘
5、一边通过输入流读取客户端发送的数据,一边写出到D盘
6、通知客户端文件接收完成
7、关闭所有流
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 此案例为tcp的练习文件上传的服务器端代码
*/
public class FIleUploadServer {
public static void main(String[] args) throws IOException {
1、创建服务器对象
ServerSocket ss = new ServerSocket(8899);
// 2、接受客户端连接请求--阻塞
Socket socket = ss.accept();
// 3、获取一个输入流
InputStream in = socket.getInputStream();
// 4、准备一个输出流 将数据写出到e
FileOutputStream out = new FileOutputStream("e:\\jdk.CHM");
// 5、一边通过输入流读取客户端发送的数据,一边写出到e
byte[] bytes = new byte[1024];
int len;
while((len=in.read(bytes))!=-1){
//当前已经接收了客户端发送的一部分的数据
//将这部分数据写出到e盘
out.write(bytes,0,len);
}
// 6、通知客户端文件接收完成
socket.shutdownInput();
//新增一个功能 当文件接收完成,给客户端一个回复
OutputStream out1 = socket.getOutputStream();
out1.write("文件上传成功".getBytes());
//通知客户端数据写出完成
socket.shutdownOutput();
// 7、关闭所有流
ss.close();
out.close();
}
}
单例设计模式
设计模式:
有多年开发经验,行业经验,总结了一套解决常见问题的套路
单例设计模式
在全局中只能有一个实例
饿汉式:
classRWGlq{
//定义当前类的一个对象
privatestaticRWGlqrwGlq=newRWGlq();
//不能通过new创建对象所以构造方法私有化
privateRWGlq(){}
//提供公开的方法返回rwGlq
publicstaticRWGlqgetInstance(){
returnrwGlq;
}
}
懒汉式:
classRWGlq{
//定义当前类的一个对象
privatestaticRWGlqrwGlq;
//不能通过new创建对象所以构造方法私有化
privateRWGlq(){}
//提供公开的方法返回rwGlq
publicstaticRWGlqgetInstance(){
//当需要获取当前对象时才来创建
rwGlq=newRWGlq();
returnrwGlq;
}
}
比较
饿汉式:是否不管是否有人获取对象,在类加载是就创建对象;浪费了部分空间,占用资源;但饿汉式不存在多线程并发安全问题
懒汉式:什么时候使用对象,什么时候创建对象;节省资源。但懒汉式可能会出现多线程并发安全问题
总结:
应用场景:
比如:只有一个班长,一个身份证
步骤:
1、私有化构造方法
2、定义当前类的对象作为属性
3、提供静态的方法 返回值是
JDK1.5
静态导入包:
在导包时,可以加static关键字,导热油静态的方法;
优点:
无关的方法无序导入,节省资源
缺点:
因为静态导入之后,使用静态方法无需类名调用,这样会引起混淆
枚举
可变参数
总结:
IO-网络编程(套接字)
IP 端口 域名 DNS解析
SocketAddress:抽象类
InetSocketAddress:
传输层:
UDP
特点:
1、不需要连接
2、不可靠
3、传输效率高
应用场景:视频通话 直播
DatagramSocket :发送数据 接受数据
DatagramPacket :数据报包
单人聊天
TCP:
特点:
1、需要建立连接
2、可靠性
3、传输效率低
4、不限制大小
应用场景:文件上传,下载
客户端:Socket
connect
服务器端:ServerSocket
accept
发送数据接收数据:流
从Socket对象可以获取基于连接的输入和输出流
文件上传
单例设计模式:在全局只产生一个唯一的实例
1、私有化构造方法
2、在勒种提供一个本类的属性
3、提供一个公开的静态方法