针对不同网站的cdn加速,模板之家官网手机模板,重庆在线官网,网页模板免费网址文章目录 1. 网络编程基础1.1 为什么需要网络编程#xff1f;1.2 网络编程是什么#xff1f;1.3 概念 2. Socket套接字3. UDP数据报套接字编程3.1 DatagramSocket API3.2 DatagramPacket API3.3 InetSocketAddress API 4. UDP构建服务端客户端#xff08;一发一收#xff0… 文章目录 1. 网络编程基础1.1 为什么需要网络编程1.2 网络编程是什么1.3 概念 2. Socket套接字3. UDP数据报套接字编程3.1 DatagramSocket API3.2 DatagramPacket API3.3 InetSocketAddress API 4. UDP构建服务端客户端一发一收4.1 创建服务端UdpServer.java4.2 创建客户端UdpClient.java 5. UDP构建服务端客户端翻译6. TCP流套接字编程6.1 ServerSocket API6.2 Socket API6.3 TCP中的长短连接 7. TCP构建服务端客户端一发一收7.1 创建服务端TcpServer.java7.2 创建客户端TcpClient.java 8. 启动多个客户端 1. 网络编程基础
1.1 为什么需要网络编程 这是因为在我们本地资源中里面的内容并不丰富而且下载的资源大多最终还是来源于网络。 而在网络世界中里面有大量的资源。例如当我们在网页中打开一个视频听一段音乐看一篇文章等这些都属于网络资源能从网络中获得的数据资源。 这些资源都是通过网络编程进行数据传输所以网络编程的需要是必不可少的。 1.2 网络编程是什么 网络编程就是指网络主机通过不同的进程以编程的方式进行网络通信或称网络数据传输。 1.3 概念 发送端数据发送方的进程称发送端。发送端的主机即网络通信中的源主机。接收端数据接受方的进程称接受端。接受端的主机即网络通信中的目的主机。收发端发送端和接受端简称收发端。 注意 发送端和接收端只是相对的只是一次网络数据传输产生数据流向后的概念。 如上图进程1请求获得资源时进程1就是发送端进程2是接收端进程2响应时进程2就是发送端进程1就是接收端。服务端提供服务的一端称为服务端。客户端获取服务的一端称为客户端。 如上图主机1发出请求主机2做出响应那么我们就可以称主机1为客户端主机2为服务端。 2. Socket套接字 概念 Socket套接字是由系统提供用于网络通信的技术是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。 分类 流套接字使用传输层TCP协议。 TCP的特点 有连接 可靠传输 面向字节流 有接收缓冲区也有发送缓冲区 大小不限数据报套接字使用传输层UDP协议 UDP的特点 无连接 不可靠传输 面向数据报 有接收缓冲区无发送缓冲区 大小受限一次最多传输64k原始套接字原始套接字用于自定义传输层协议用于读写内核没有处理的IP协议数据。 3. UDP数据报套接字编程
3.1 DatagramSocket API DatagramSocket 是UDP Socket用于发送和接收UDP数据报。 DatagramSocket 构造方法
方法作用DatagramSocket()创建一个UDP数据报套接字的Socket绑定到本机任意一个随机端口一般用于客户端DatagramSocket()创建一个UDP数据报套接字的Socket绑定到本机指定的端口一般用于服务端 //创建一个UDP数据报套接字的Socket绑定到本机任意一个随机端口DatagramSocket socket1 new DatagramSocket();//创建一个UDP数据报套接字的Socket绑定到本机9090端口DatagramSocket socket2 new DatagramSocket(9090);DatagramSocket 方法
方法作用void receive(DatagramPacket p)从此套接字接收数据报如果没有接收到数据报该方法会阻塞等待void send(DatagramPacketp)从此套接字发送数据报包不会阻塞等待直接发送void close()关闭此数据报套接字
3.2 DatagramPacket API DatagramPacket是UDP Socket发送和接收的数据报。 DatagramPacket 构造方法
方法作用DatagramPacket(byte[] buf, int length)构造一个DatagramPacket以用来接收数据报接收的数据保存在字节数组第一个参数buf中接收指定长度第二个参数length)DatagramPacket(byte[] buf, int offset, int length, SocketAddress address)构造一个DatagramPacket以用来发送数据报发送的数据为字节数组第一个参数buf中从0到指定长度第二个参数length。address指定目的主机的IP和端口号
DatagramPacket 方法:
方法作用InetAddress getAddress()从接收的数据报中获取发送端主机IP地址或从发送的数据报中获取接收端主机IP地址int getPort()从接收的数据报中获取发送端主机的端口号或从发送的数据报中获取接收端主机端口号byte[] getData()获取数据报中的数据
3.3 InetSocketAddress API 构造UDP发送的数据报时需要传入 SocketAddress 该对象可以使用 InetSocketAddress 来创建。 InetSocketAddress SocketAddress 的子类 构造方法
方法作用InetSocketAddress(InetAddress addr, int port)创建一个Socket地址包含IP地址和端口号
4. UDP构建服务端客户端一发一收 知道上面的就可以创建一个简单的服务端客户端一发一收就是客户端请求服务端请求什么客户端收到什么。 4.1 创建服务端UdpServer.java
public class UdpServer {//创建服务器socket不实例化private DatagramSocket socket null;public UdpServer(int port) throws SocketException {服务器socket绑定固定的端口socket new DatagramSocket(port);}public void start() throws IOException {System.out.println(服务器启动);//服务器放入死循环中我们并不知道客户端什么时候访问客户端需要不停的接受客户端的UDP数据报while(true){//1.创建数据报读取客户端发送数据DatagramPacket requestPacket new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//转义String request new String(requestPacket.getData(),0,requestPacket.getLength());//2.响应String response process(request);//3.返回客户端//计算机内部处理数据的基本单位是字节。通过将接收到的数据转义为字节长度要用字节长度DatagramPacket responsePacket new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf([%s:%d] req: %s, resp: %s\n,requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}//一发一收public String process(String request){return request;}public static void main(String[] args) throws IOException {//实例化服务端端口号为9092UdpServer udpServer new UdpServer(9092);//启动服务端udpServer.start();}
}4.2 创建客户端UdpClient.java
public class UdpClient {private DatagramSocket socket null;private String serverIp;private int serverPort;public UdpClient(String ip, int port) throws SocketException {serverIp ip;serverPort port;socket new DatagramSocket();}public void start() throws IOException {System.out.println(客户端启动);Scanner sc new Scanner(System.in);while(true){//1.输入System.out.println(- );String request sc.next();//2.发送
// InetSocketAddress inetAddress new InetSocketAddress(serverIp,serverPort);
// DatagramPacket requestPacket new DatagramPacket(request.getBytes(),request.getBytes().length,
// inetAddress);
// 计算机内部处理数据的基本单位是字节。通过将接收到的数据转义为字节长度要用字节长度DatagramPacket requestPacket new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIp),serverPort);socket.send(requestPacket);//3.读取DatagramPacket responsePacket new DatagramPacket(new byte[4096],0,4096);socket.receive(responsePacket);String response new String(responsePacket.getData(),0,responsePacket.getLength());//4.显示System.out.println(response );}}public static void main(String[] args) throws IOException {UdpClient udpClient new UdpClient(127.0.0.1,9092);udpClient.start();}
}运行结果
5. UDP构建服务端客户端翻译 4中服务器并没有什么功能那么我们也可以为服务器赋予一些功能例如翻译。 我们只需要基于4代码的基础上对服务器进行修改。 创建翻译服务端UdpServer.java
public class UdpServer {//创建服务器socket不实例化private DatagramSocket socket null;//翻译集合private MapString,String dict new HashMap();public UdpServer(int port) throws SocketException {//服务器socket绑定固定的端口socket new DatagramSocket(port);//添加单词dict.put(cat,小猫);dict.put(dog,小狗);dict.put(bird,鸟);}public void start() throws IOException {System.out.println(服务器启动);//服务器放入死循环中我们并不知道客户端什么时候访问客户端需要不停的接受客户端的UDP数据报while(true){//1.创建数据报读取客户端发送数据DatagramPacket requestPacket new DatagramPacket(new byte[4096],4096);socket.receive(requestPacket);//转义计算机内部处理数据的基本单位是字节。通过将接收到的数据转义为字节服务器可以更容易地处理和解析数据不会出错String request new String(requestPacket.getData(),0,requestPacket.getLength());//2.响应String response process(request);//3.返回客户端DatagramPacket responsePacket new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf([%s:%d] req: %s, resp: %s\n,requestPacket.getAddress().toString(),requestPacket.getPort(),request,response);}}//一发一收public String process(String request){return dict.getOrDefault(request,我还是个小菜鸡);}public static void main(String[] args) throws IOException {//实例化服务端端口号为9092UdpServer udpServer new UdpServer(9092);//启动服务端udpServer.start();}
}运行结果 其实相对于4只是修改了一些方法和属性那么我们也可以重新写一个类继承4中的服务器这样会更加的简单。
6. TCP流套接字编程 ServerSocket 是创建TCP服务端Socket的API。 6.1 ServerSocket API
ServerSocket 构造方法
方法作用ServerSocket(int port)创建一个服务端流套接字Socket并绑定到指定端口
ServerSocket 方法
方法作用Socket accept()开始监听指定端口创建时绑定的端口有客户端连接后返回一个服务端Socket对象并基于该Socket建立与客户端的连接否则阻塞等待void close()关闭此套接字
6.2 Socket API Socket 是客户端Socket或服务端中接收到客户端建立连接accept方法的请求后返回的服务端Socket。 不管是客户端还是服务端Socket都是双方建立连接以后保存的对端信息及用来与对方收发数据的。 Socket 构造方法
方法作用Socket(String host, intport)创建一个客户端流套接字Socket并与对应IP的主机上对应端口的进程建立连接
Socket 方法
方法作用InetAddress getInetAddress()返回套接字所连接的地址InputStream getInputStream()返回此套接字的输入流OutputStream getOutputStream()返回此套接字的输出流
6.3 TCP中的长短连接 TCP发送数据时需要先建立连接什么时候关闭连接就决定是短连接还是长连接 短连接每次接收到数据并返回响应后都关闭连接即是短连接。也就是说短连接只能一次收发数据。长连接不关闭连接一直保持连接状态双方不停的收发数据即是长连接。也就是说长连接可以多次收发数据。 对比以上长短连接两者区别如下 建立连接、关闭连接的耗时短连接每次请求、响应都需要建立连接关闭连接而长连接只需要第一次建立连接之后的请求、响应都可以直接传输。相对来说建立连接关闭连接也是要耗时的长连接效率更高。主动发送请求不同短连接一般是客户端主动向服务端发送请求而长连接可以是客户端主动发送请求也可以是服务端主动发。两者的使用场景有不同短连接适用于客户端请求频率不高的场景如浏览网页等。长连接适用于客户端与服务端通信频繁的场景如聊天室实时游戏等。 7. TCP构建服务端客户端一发一收
7.1 创建服务端TcpServer.java
public class TcpServer {private ServerSocket serverSocket null;private ExecutorService service Executors.newCachedThreadPool();public TcpServer(int port) throws IOException {serverSocket new ServerSocket(port);}public void start() throws IOException {System.out.println(服务器启动);while(true){Socket socket serverSocket.accept();service.submit(new Runnable() {Overridepublic void run() {processConnection(socket);}});
// Thread thread new Thread(() - {
// processConnection(socket);
// });
// thread.start();}}public void processConnection(Socket socket){System.out.printf(客户端上线: [%s:%d]\n,socket.getInetAddress().toString(),socket.getPort());try(InputStream inputStream socket.getInputStream();OutputStream outputStream socket.getOutputStream()){while(true){Scanner sc new Scanner(inputStream);if(!sc.hasNext()){System.out.printf(客户端下线: [%s:%d]\n,socket.getInetAddress().toString(),socket.getPort());break;}String request sc.next();String response process(request);PrintWriter writer new PrintWriter(outputStream);writer.println(response);writer.flush();System.out.printf([%s:%d] req: %s, resp: %s\n,socket.getInetAddress().toString(),socket.getPort(),request,response);}}catch (IOException e){e.printStackTrace();}finally {try {socket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpServer tcpServer new TcpServer(9090);tcpServer.start();}
}7.2 创建客户端TcpClient.java
public class TcpClient {private Socket socket null;public TcpClient(String ip, int port) throws IOException {socket new Socket(ip,port);}public void start(){System.out.println(客服端启动);Scanner sc new Scanner(System.in);try(InputStream inputStream socket.getInputStream();OutputStream outputStream socket.getOutputStream()){while(true){System.out.println(- );String request sc.next();PrintWriter writer new PrintWriter(outputStream);writer.println(request);writer.flush();Scanner scanner new Scanner(inputStream);String response scanner.next();System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpClient tcpClient new TcpClient(127.0.0.1,9090);tcpClient.start();}
}Tcp简单翻译和Udp修改规则相同。
8. 启动多个客户端 1. 2. 3. 4.