UDP网络通信的收包过程:
使用DatagramSocket()创建一个数据包套接字,绑定到指定的端口。
使用DatagramPacket(byte[]buf,int length)创建字节数组来接收数据包.
使用DatagramPacket类的receive()方法接收UDP。
TCP网络程序
=====================================================================
ServerSocket类
Java.net包中的ServerSocket类用于表示服务器套接字,其主要功能是监听客户端的请求,然后将客户端的请求连接存入队列中,默认请求队列大小是50。
构造方法主要有以下几种形式:
ServerSocket():创建非绑定服务器套接字。
ServerSocket(int port):创建绑定到特定端口的服务器套接字。
ServerSocket(int port,int backlog):利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号。
ServerSocket(int port,int backlog,InetAdress bindAddress):使用指定的端口、监听backlog和要绑定到本地IP地址创建服务器,适用于计算机有多个网卡、多个IP的情景。
实例:
//服务端程序
import java.io.*;
import java.net.*;
public class MyTcpServer {
private BufferedReader reader;
private PrintWriter writer;
private ServerSocket server;
private Socket socket;
void getserver(){
try{
server = new ServerSocket(8866);
System.out.println(“服务器套接字已经创建成功”);
while(true){
System.out.println(“等待客户机的连接”);
socket = server.accept(); //阻塞的
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(),true);
getClientMessage(); }
}catch(Exception e){
e.printStackTrace();
}
}
private void getClientMessage(){
try{
while(true){
System.out.println(“客户端信息接收:”+ reader.readLine());
writer.println(“欢迎您连接服务端”);
}
}catch(Exception e){
e.printStackTrace();
}
try{
if(reader != null){
reader.close();
}
if(writer != null){
writer.close();
}
if(socket != null){
socket.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
MyTcpServer tcpserv = new MyTcpServer();
tcpserv.getserver();
}
}
//客户端程序
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class MyTcpClient {
private PrintWriter writer;
private BufferedReader reader;
Socket socket;
public void connect(){
System.out.println(“尝试连接”);
try{
socket = new Socket(“127.0.0.1”,8866);
writer = new PrintWriter(socket.getOutputStream(),true);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(“连接成功”);
writer.println(“你好,来自客户端的连接”);
getserverMessage();
}catch(Exception e){
e.printStackTrace();
}
}
private void getserverMessage(){
try{
while(true){
System.out.println(":"+ reader.readLine());
}
}catch(Exception e){
e.printStackTrace();
}
try{
if(reader != null){
reader.close();
}
if(writer != null){
writer.close();
}
if(socket != null){
socket.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public class Main {
public static void main(String[] args) {
MyTcpClient tcpclient;
tcpclient = new MyTcpClient();
tcpclient.connect();
}
}
服务端控制台:
客户端控制台:
总结:网络编程是程序实现网络通信的基石,在互联网高度繁荣的当下,几乎没有什么应用不需要网络支持。网络通信基于TCP/IP,基于此,网络编程可以选择使用TCP传输或UDP传输,它们两个是比较底层的通信协议,TCP提供可靠的连接,UDP则不提供可靠的连接,在实际应用中大多数选用TCP,而UDP主要用于音视频、NTP对时这种对数据可靠性要求不是那么高的场合。
IO模型
==================================================================
对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区page cache中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。所以说,当一个read操作发生时,它会经历两个阶段:
等待数据准备
将数据从内核拷贝到进程中
IO模型的分类有下:
阻塞 I/O(blocking IO)
非阻塞 I/O(nonblocking IO)
I/O 多路复用( IO multiplexing)
异步 I/O(asynchronous IO)
BIO 阻塞 I/O
缺点:一个请求一个线程,浪费线程,且上下文切换开销大;
当用户进程调用了recvfrom这个系统调用,kernel就开始了IO的第一个阶段:准备数据(对于网络IO来说,很多时候数据在一开始还没有到达。比如,还没有收到一个完整的UDP包。这个时候kernel就要等待足够的数据到来)。这个过程需要等待,也就是说数据被拷贝到操作系统内核的缓冲区中是需要一个过程的。而在用户进程这边,整个进程会被阻塞(当然,是进程自己选择的阻塞)。当kernel一直等到数据准备好了,它就会将数据从kernel中拷贝到用户内存,然后kernel返回结果,用户进程才解除block的状态,重新运行起来。
NIO 非阻塞 I/O
当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error 。从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。
nonblocking IO的特点是用户进程需要不断的主动询问kernel数据好了没有。
I/O 多路复用
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
IO multiplexing就是我们说的select,poll,epoll,有些地方也称这种IO方式为event driven IO。select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select,poll,epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。
机制:一个线程以阻塞的方式监听客户端请求;另一个线程采用NIO的形式select已经接收到数据的channel信道,处理请求;Linux的多种IO模型以及select,poll,epoll模型 - 处理更多的连接。