哈密建设局网站,上海装修公司排名前十名,wordpress站内301,经营网站建设文章目录 一、概念1.1 什么是网络编程1.2 网络编程中的基本知识 二、Socket套接字2.1 概念及分类2.2 TCP VS UDP2.3 通信模型2.4 接口方法UDP数据报套接字编程TCP流套接字编程 三、代码示例3.1 注意点3.2 回显服务器基于UDP基于TCP 一、概念 首先介绍了什么是网络编程#xff… 文章目录 一、概念1.1 什么是网络编程1.2 网络编程中的基本知识 二、Socket套接字2.1 概念及分类2.2 TCP VS UDP2.3 通信模型2.4 接口方法UDP数据报套接字编程TCP流套接字编程  三、代码示例3.1 注意点3.2 回显服务器基于UDP基于TCP   一、概念 首先介绍了什么是网络编程随后介绍了接收端发送端、请求响应等基本知识 1.1 什么是网络编程 
网络编程 1网络上的主机通过不同的进程以编程的方式实现网络通信或称为网络数据传输。2在程序员层面上即要写一个应用程序通过调用传输层提供的API实现网络通信 
1.2 网络编程中的基本知识 发送端和接收端字面意思发送端是发送数据的接收端是接收数据的注意这个概念只是相对的主要看数据是从哪发到哪。  请求和响应 一般来说获取一个网络资源涉及到两次网络数据传输 第一次请求数据的发送第二次响应数据的发送  客户端和服务器 服务端在常见的网络数据传输场景下给用户提供服务的一方进程 客户端获取服务的一方进程是指给用户使用的程序  常见的客户端服务端模型 客户端先发送请求到服务端服务端根据请求数据执行相应的业务处理服务端返回响应发送业务处理结果客户端根据响应数据展示处理结果展示获取的资源或提示保存资源的处理结果  
二、Socket套接字 网络编程是基于Socket开发的传输层上主要涉及TCP、UDP这两种协议而他俩给出的API都不同本段主要介绍概念包括分类和区别。 2.1 概念及分类 
1Socket套接字是由系统提供用于网络通信的技术是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。 
2Socket套接字主要针对传输层协议划分为如下三类 
流套接字传输层TCP协议传输控制协议数据报套接字传输层UDP协议用户数据报协议原始套接字原始套接字用于自定义传输层协议用于读写内核没有处理的IP协议数据 
2.2 TCP VS UDP 
TCP有连接可靠传输面向字节流有接收缓冲区和发送缓冲区大小不限全双工 UDP无连接不可靠传输面向数据报有接收缓冲区无发送缓冲区大小受限一次最多传输64k 
连接客户端和服务器之间是否使用内存保存对端信息互相承认连接就建立了。传输 可靠传输A尽可能把消息传过去传输失败与否都能感知到会降低传输效率。不可靠传输传输效率更高注意这并不意味着TCP比UDP更安全因为“网络安全”指的是传输的数据是否容易被黑客截获以及如果被截获后是否会泄漏一些重要信息 字节流VS数据报 面向字节流TCP流式操作面向数据报读写的基本单位是一个UDP数据报且一次只能传输一个 全双工VS半双工 全双工一个通道可以双向通信。网线就是全双工的半双工一个通道只能单向通信  
2.3 通信模型 
数据报套接字模型 流套接字模型  
2.4 接口方法 
UDP数据报套接字编程 
UDP提供的API主要通过两个类来实现一个是DatagramSocket一个是DatagramPacket。 
DatagramSocket 方法代表一个Socket对象即一个网卡的文件 DatagramPacket 方法代表一个UDP数据报 
TCP流套接字编程 
因为TCP是字节流式传输所以不需要一个专门的类来表示TCP数据报 
ServerSocket 方法 1给服务器使用的 2负责拉客在外场广撒网。 
Socket 方法 1服务端和客户端都能用 2像是一个耳麦可以直接与对方进行通信负责在内场细致服务。 
三、代码示例 
3.1 注意点 
服务器使用的端口需要手动指定客户端的则需要系统自动分配 因为服务器需要能被客户端百分百找到万一服务器随便改变端口那客户端按照以往的连接是无法连接到服务器的。客户端则没有这个需求且客户端一旦指定端口号很可能回合其他程序冲突系统自动分配的端口号一定是空闲的。 flush() ------ 手动刷新 IO操作是比较有开销的相比于访问内存进行IO次数越多程序的速度就越慢。为了解决这个问题我们会使用一块内存作为缓冲区写数据的时候先写到缓冲区里。攒了一波数据之后统一进行IO。printWriter 内置了缓冲区flush()可以实现手动刷新可以确保这里的数据是真的通过网卡发出去了而不是残留在内存缓冲区中的加上flush()可以让代码更稳妥但是不加不一定会出错因为缓冲区内置了一定的刷新策略 关于 close() close() 主要是删除文件描述符表中的记录。当然也并不是每个流对象都有文件描述符表只有那种调用了操作系统提供的open()方法涉及到了用户态和用户态。 
3.2 回显服务器 
基于UDP 1InetAddress 表示的是IP地址 2客户端要设置要传给的服务器的IP地址和端口号是多少即示例中的 serverIp 和 serverPort 。服务器则是要手动指定一个端口号。 3难点在于 DatagramPacket 的构造涉及了String 和 DatagramPacket 之间的转换。 4数据包的接收和发送依靠 DatagramSocket 的 send 和 receive 方法。 //客户端
public class UdpEchoClient {private DatagramSocket socket  null;private String serverIp;private int serverPort;public UdpEchoClient(String ip, int port) throws SocketException {serverIp  ip;serverPort  port;socket  new DatagramSocket();}public void start() throws IOException {//获取用户输入的内容Scanner scanner  new Scanner(System.in);System.out.println(客户端启动);//给服务器发送响应while (true){System.out.print(- );String request  scanner.next();//不能用request.length()因为这是指字符长度我们需要的是字节长度//除非是纯英文且由utf-8编码那么两者会相同。Socket是按照字节来处理的。DatagramPacket requestPacket  new DatagramPacket(request.getBytes(), request.getBytes().length,InetAddress.getByName(serverIp), serverPort);socket.send(requestPacket);//接收响应DatagramPacket responsePacket  new DatagramPacket(new byte[4096], 4096);socket.receive(responsePacket);String response  new String(responsePacket.getData(), 0, responsePacket.getLength());System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client  new UdpEchoClient(127.0.0.1, 9090);client.start();}
} 
//服务器
public class UdpEchoServer {private DatagramSocket socket  null;public UdpEchoServer(int port) throws SocketException {socket  new DatagramSocket(port);}public void start() throws IOException {System.out.println(服务器启动);while(true){DatagramPacket requestPacket  new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);String request  new String(requestPacket.getData(), 0, requestPacket.getLength());String response  process(request);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 {UdpEchoServer server new UdpEchoServer(9090);server.start();}
}基于TCP 
服务器对客户是多对多的关系一个服务器内核会存许多客户端的连接建立连接的过程系统内核会自己完成。连接就像是一个个代办事项等待应用程序一个个完成。serverSocket.accept()将在内核中已经建立好的连接取出来给应用程序原理是一个【生产者消费者模型】 TCP中的长短连接 短连接每次接收到数据并返回响应后都关闭连接即只能一次收发数据长连接不关闭连接一直保持连接状态双方不停的收发数据  
public class TcpServer {private ServerSocket socket  null;private ExecutorService service  Executors.newCachedThreadPool();public TcpServer(int port) throws IOException {socket  new ServerSocket(9090);}public void start() throws IOException {System.out.println(服务端启动);while (true){Socket clientSocket  socket.accept();//为了能够接收多个客户端这里使用了线程池//当客户端进一步增加线程数目也会增加系统的负担也就越来越重响应速度也就越来越慢//为了解决这个问题就需要开源引入更多的硬件资源节流减少每种硬件资源占用的资源service.submit(new Runnable() {Overridepublic void run() {try {processConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}}});}}public void processConnection(Socket clientSocket) throws IOException {try(InputStream inputStream  clientSocket.getInputStream();OutputStream outputStream  clientSocket.getOutputStream()){while(true){Scanner scannerClient  new Scanner(inputStream);String request  scannerClient.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, clientSocket.getInetAddress().toString(),clientSocket.getPort(), request, response);}} catch (IOException e) {throw new RuntimeException(e);}finally {clientSocket.close();}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpServer server  new TcpServer(9090);server.start();}
} 
public class TcpClient {private Socket socket  null;public TcpClient(String serverIp, int serverPort) throws IOException {socket  new Socket(serverIp, serverPort);}public void start(){System.out.println(客户端启动);Scanner scanner  new Scanner(System.in);try(InputStream inputStream  socket.getInputStream();OutputStream outputStream  socket.getOutputStream()){while (true){System.out.print(----);String request  scanner.next();PrintWriter writer  new PrintWriter(outputStream);writer.println(request);writer.flush();Scanner scammerConsole  new Scanner(inputStream);String response  scammerConsole.next();System.out.println(response);}} catch (IOException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException {TcpClient client  new TcpClient(127.0.0.1, 9090);client.start();}
}