Java程序设计(高级及专题)- 网络编程,java架构师直通车吾爱破解

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模型 - 处理更多的连接。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容