发布时间:2024-01-16 10:00
主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率
等
作用:传输比特流(就是由 1、0 转化为电流强弱来进行传输,到达目的地后在转化为
1、0,也就是我们常说的模数转换与数模转换)
作用:主要将从物理层接收的数据进行 MAC 地址(网卡的地址)的封装与解封装
作用:主要将从下层接收到的数据进行 IP 地址(例 192.168.0.1)的封装与解封装。在这一层工
作的设备是路由器,常把这一层的数据叫做数据包。
作用:主要是将从下层接收的数据进行分段进行传输,到达目的地址后在进行重组。
常常把这一层数据叫做段。
作用:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路。主要在你的系统之间
发起会话或或者接受会话请求(设备之间需要互相认识可以是 IP 也可以是 MAC 或者是主机名)
作用:主要是进行对接收的数据进行解释、加密与解密、压缩与解压缩等(也就是把计算机能够
识别的东西转换成人能够能识别的东西(如图片、声音等))
作用:主要是一些终端的应用,为应用进程提供服务,比如说FTP(各种文件下载),WEB(IE浏览),QQ之类的(你就把它理解成我们在电脑屏幕上可以看到的东西.就 是终端应用)。
阻塞IO中从用户发起调用开始,数据等待、数据拷贝都是需要用户进程,直到数据拷贝完成返回,用户进程才可以继续执行,否则一直阻塞。
非阻塞IO中进程通过反复调用IO函数,判断数据是否准备好,采用轮询,占用CPU。
主要使用复用器:select、poll、epoll
一个进程可以监听多个事件,能实现对多个端口进行监听,多个连接共享一个等待机制。
首先需要开启套接字信号驱动功能,通过系统调用sinaction执行信号处理函数,信号处理函数直接返回,进程继续工作,当数据准备就绪,生成一个siglo信号,通知应用程序取数据。
信号驱动IO由内核通知进程开始一个IO操作,在用户进程进行IO操作的时候是需要等待的,所以是同步过程。
异步IO模型是由内核通知IO何时已经完成,进程不需要进行IO处理,所以是异步的。
/**
服务端
*/
public class Server {
public static void main(String[] args) {
serverHandler(9999);
}
public static void serverHandler(int port) {
ServerSocket serverSocket = null;
try {
//1、创建ServerSocket实例
serverSocket = new ServerSocket();
//2、绑定端口
serverSocket.bind(new InetSocketAddress(port));
System.out.println(\"服务端绑定端口:\"+port+\" 并启动啦\");
//3、监听客户端的连接.会阻塞直到有客户端连接上
Socket socket = serverSocket.accept();
System.out.println(\"有新客户端连接:\"+socket.getRemoteSocketAddress());
byte[] bytes = new byte[1024];
InputStream inputStream = socket.getInputStream();//读数据
OutputStream outputStream = socket.getOutputStream();//写数据
//多次接收用户端发送的消息,并返回数据
while (true) {
//读数据
int len = inputStream.read(bytes);
String msg = new String(bytes,0,len);
System.out.println(\"客户端:\"+socket.getRemoteSocketAddress()+\" 发送数据:\"+msg);
//给客户端回写数据
String msg1 = \"【echo】\"+msg;
outputStream.write(msg1.getBytes());
outputStream.flush();
//特殊标志位表示结束 exit
if (msg != null && \"exit\".equals(msg.trim())) {
//特殊结束符
System.out.println(\"服务端准备结束\");
break;
}
}
//关闭socket
socket.close();
System.out.println(\"客户端连接已断开\");
} catch (IOException e) {
e.printStackTrace();
}finally {
if (serverSocket != null) {
try {
serverSocket.close();
System.out.println(\"服务端已关闭\");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
```java
/**
* 客户端
*/
public class Client {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
clientHandler(\"127.0.0.1\",9999);
}
public static void clientHandler(String ip,int port) {
try {
//1、创建socket实例
Socket socket = new Socket();
System.out.println(\"客户端启动啦\");
//2、连接服务端
socket.connect(new InetSocketAddress(ip,port));
System.out.println(\"客户端连接上服务端\");
//进行读写操作
OutputStream outputStream = socket.getOutputStream();//发消息
InputStream inputStream = socket.getInputStream();//收消息
byte[] bytes = new byte[1024];
while (scanner.hasNext()) {
String msg = scanner.nextLine();
if (msg == null || \"\".equals(msg.trim())) continue;
//写数据
outputStream.write(msg.getBytes());
outputStream.flush();
//接收返回数据
int num = inputStream.read(bytes);
System.out.println(new String(bytes,0,num));
if (\"exit\".equals(msg)) break;
}
System.out.println(\"客户端即将结束\");
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MutilThreadServer {
public static void main(String[] args) {
serverHandler(9999);
}
public static void serverHandler(int port) {
ServerSocket serverSocket = null;
try {
//1、创建ServerSocket实例
serverSocket = new ServerSocket();
//2、绑定端口
serverSocket.bind(new InetSocketAddress(port));
System.out.println(\"服务端绑定端口:\"+port+\" 并启动啦\");
//3、监听客户端的连接.会阻塞直到有客户端连接上
while (true) {
Socket socket = serverSocket.accept();
System.out.println(\"有新客户端连接:\"+socket.getRemoteSocketAddress());
//将新用户连接交给子线程处理并启动子线程
new ServerHandler(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if (serverSocket != null) {
try {
serverSocket.close();
System.out.println(\"服务端已关闭\");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 子线程完成读写操作
*/
public class ServerHandler extends Thread {
Socket socket;
//构造函数,将新用户的连接socket交给子线程
public ServerHandler(Socket socket){
this.socket = socket;
}
@Override
//子线程完成读写操作
public void run() {
try {
//
byte[] bytes = new byte[1024];
InputStream inputStream = socket.getInputStream();//读数据
OutputStream outputStream = socket.getOutputStream();//写数据
//多次接收用户端发送的消息,并返回数据
while (true) {
//读数据
int len = inputStream.read(bytes);
String msg = new String(bytes,0,len);
System.out.println(\"线程:\"+Thread.currentThread().getName()+\" 客户端:\"+socket.getRemoteSocketAddress()+\" 发送数据:\"+msg);
//给客户端回写数据
String msg1 = \"【echo】\"+msg;
outputStream.write(msg1.getBytes());
outputStream.flush();
//特殊标志位表示结束 exit
if (msg != null && \"exit\".equals(msg.trim())) {
//特殊结束符
System.out.println(\"线程:\"+Thread.currentThread().getName()+\"服务端准备结束\");
break;
}
}
//关闭socket
socket.close();
System.out.println(\"线程:\"+Thread.currentThread().getName()+\"客户端连接已断开\");
} catch (Exception e){
}
}
}
public abstract class FileChannel extends AbstractInterruptibleChannel
implements SeekableByteChannel, GatheringByteChannel ScatteringByteChannel
{
protected FileChannel() { }
public static FileChannel open(Path path,Set<? extends OpenOption> options,FileAttribute<?>... attrs) throws IOException
{
FileSystemProvider provider = path.getFileSystem().provider();
return provider.newFileChannel(path, options, attrs);
}
public static FileChannel open(Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs)
throws IOException
{
FileSystemProvider provider = path.getFileSystem().provider();
return provider.newFileChannel(path, options, attrs);
}
- DatagramChannel
- SocketChannel
- ServerSocketChannel
public class Server {
public static void main(String[] args) {
try {
//创建异步通信channel
AsynchronousServerSocketChannel asynchronousServerSocketChannel = AsynchronousServerSocketChannel.open();
//绑定端口
asynchronousServerSocketChannel.bind(new InetSocketAddress(9999));
System.out.println(\"server端启动啦\");
//异步调用
asynchronousServerSocketChannel.accept(null,new AcceptHandler(asynchronousServerSocketChannel));
//该操作是异步操作,为了方式当前线程直接执行结束,人为设置阻塞
while (true) {
Thread.sleep(1000);
System.out.println(\"循环中...\");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class AcceptHandler implements CompletionHandler<AsynchronousSocketChannel,Object> {
private AsynchronousServerSocketChannel asynchronousServerSocketChannel;
public AcceptHandler(AsynchronousServerSocketChannel asynchronousServerSocketChannel) {
this.asynchronousServerSocketChannel = asynchronousServerSocketChannel;
}
@Override
public void completed(AsynchronousSocketChannel channel, Object server) {
//IO成功之后,返回是accept接收的AsynchronousSocketChannel
try {
System.out.println(\"有新客户端连接:\"+channel.getRemoteAddress());
} catch (IOException e) {
e.printStackTrace();
}
//读取数据
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
//异步读
channel.read(buffer,buffer,new ReadHandler(channel));
//继续接受客户端端的连接
asynchronousServerSocketChannel.accept(null,new AcceptHandler(asynchronousServerSocketChannel));
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
}
public class ReadHandler implements CompletionHandler<Integer,ByteBuffer> {
private AsynchronousSocketChannel channel;
public ReadHandler(AsynchronousSocketChannel channel) {
this.channel = channel;
}
@Override
public void completed(Integer result, ByteBuffer buffer) {
//读取到用户的数据
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String msg = new String(bytes);
System.out.println(\"读取到数据:\"+msg);
//继续接受数据
buffer.clear();
channel.read(buffer,buffer,new ReadHandler(channel));
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
}
ServerSocket ss =null;
try {
//创建ServerSocket实例并绑定端口6666
ss = new ServerSocket(6666);
//等待客户端连接 accept()等待连接,如果有用户连接是使用TCP的三次握手机制来建立连接
Socket socket = ss.accept();
System.out.println(\"有新客户端的连接\");
//获取连接对象的输入流
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
//获取客户端发送的输入信息
String msg = in.readLine();
System.out.println(\"客户端接收到的数据:\"+msg);
if (\"exit\".equals(msg)) break;
}
//关闭资源
in.close();
socket.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
//创建socket实例
Socket socket = new Socket();
//连接服务端 connect客户端连接服务器 底层TCP主动发起连接服务端请求建立连接
socket.connect(new InetSocketAddress(\"127.0.0.1\",6666));
OutputStream os = socket.getOutputStream();
//接收键盘输入的数据
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print(\"请输入内容:\");
String msg = in.readLine();
if (msg == null || \"\".equals(msg.trim())) continue;
os.write((msg+\"\\n\").getBytes());
os.flush();
if (\"exit\".equals(msg)) break;
}
//关闭资源
os.close();
in.close();
socket.close();
import java.io.IOException;
import java.net.*;
public class UDPServer2022 {
public static void main(String[] args) throws IOException {
//构建发送对象
DatagramSocket datagramSocket = new DatagramSocket();
//将数据打包成数据报
String info = \"hello Java\";
DatagramPacket datagramPacket = new DatagramPacket(info.getBytes(), info.length(), InetAddress.getByName(\"localhost\"), 6666);
//发送数据报
datagramSocket.send(datagramPacket);
System.out.println(\"已发送数据\");
}
}
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class UDPClient2022 {
public static void main(String[] args) throws IOException {
//创建UDP Socket接收服务端的数据
DatagramSocket datagramSocket = new DatagramSocket(6666);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 1024);
System.out.println(\"等待接收数据\");
//接收数据
datagramSocket.receive(datagramPacket);
//可以读取数据
String info = new String(datagramPacket.getData(), 0, datagramPacket.getLength());
System.out.println(info);
}
}