当前位置: 首页 > news >正文

百度网站两两学一做心得体会外贸中间体做哪个网站好

百度网站两两学一做心得体会,外贸中间体做哪个网站好,系统开发板,免费信息推广网站前集回顾 上一篇博客中我们写了一个UDP的echo server#xff0c;是一个回显服务器#xff1a;请求是啥#xff0c;响应就是啥 一个正常的服务器#xff0c;要做三个事情#xff1a; 读取请求并解析根据请求#xff0c;计算响应把响应写回到客户端 DatagramPacket res…前集回顾 上一篇博客中我们写了一个UDP的echo server是一个回显服务器请求是啥响应就是啥 一个正常的服务器要做三个事情 读取请求并解析根据请求计算响应把响应写回到客户端 DatagramPacket responsePacket new DatagramPacket(response.getBytes(), 0, response.getBytes().length,requestPacket.getSocketAddress()); //先得到字节数组然后取字节然后取数组的长度这里的长度单位是“字节数” String request new String(requestPacket.getData(), 0, requestPacket.getLength()); //这里的长度单位是“字符数” 客户端的整体流程 从控制台读取字符串把字符串发送给服务器从服务器读取到响应把响应打印到控制台上 同时后面的serverIp为127.0.0.1需要把字符串格式的ip地址转成Java能识别的对象InetAddress对象提供了getByName工厂方法把上述字符串格式的ip地址转成Java能识别的InetAddress对象了 这个对象里有的就是IP地址会按照32位整数的形式来保存计算机认识的是32位整数形式的ip点分十进制是给人看的 DatagramPacket requestPacket new DatagramPacket(request.getBytes(), 0, request.getBytes().length,InetAddress.getByName(serverIp), serverPort); socket.send(requestPacket); //读取响应数据 DatagramPacket responsePacket new DatagramPacket(new byte[4096], 4096); socket.receive(responsePacket); 这个代码在写的时候上面的send完成之后就立即执行到下面的receive了但是实际上数据在网络传输过程中也是需要时间的此处的receive也会阻塞阻塞到真正到达为止 上述阻塞行为不需要咱们代码进行任何干预都是人家的api内部已经实现好了系统内核完成好了的功能 在系统内核中让某个线程阻塞是很容易的事情通过链表方式来组织PCB链表不只是一个而是有多个有的链表称为“就绪队列”这里的PCB就要参与cpu调度有的链表称为“阻塞队列”这里的PCB不参与PCB调度调用receive的时候系统会看网卡上是否有数据来了通过网卡驱动很容易能够感知到然后如果没来就把当前线程PCB放到阻塞的队列中即可链表节点的删除/插入 服务器代码 客户端代码 运行 先运行服务器后运行客户端 服务器是被动方要先准备好得餐馆先开门然后才能去吃饭 有个客户端发来一个请求请求内容是hello响应内容也是hello客户端ip是127.0.0.1客户端的port是49874系统自动分配的结果 如何启动多个客户端 默认情况下idea里面只能启动一个客户端要想启动多个需要如下操作 在service中可以看到 刚才是客户端和服务器都在同一个电脑上如果是不同电脑呢 Question如果我把客户端发给你你在客户端中填写这个ip能否访问我的这个服务器程序呢 Answer不能要想能访问有一个前提需要在同一个局域网下如何能够让世界上任何一个能上网的人脸上咱们的服务器呢不是咱们的程序代码不行代码已经就绪当前这个电脑的IP只是一个局域网内部使用的私有IP而不是能够在广域网上直接使用的“公网IP”需要一个云服务器来提供公网IP 通过XShell可以远程控制云服务器 上述一串数字就是云服务器IP也就是公网IP另外在所有IP地址中以下三种情况是私网IP剩下的都是公网IP 私网IP常用格式 10.*172.16-172.31.*192.168.* 把写好的udpechoserver放到云服务器上需要把服务器程序打一个jar包出来把这个jar包传到云服务器上运行这个程序 通过命令来运行程序 通过这串代码可以理解两方面 总结 socket apiUDP服务器程序的典型工作流程 读取请求并解析 根据请求计算响应 把响应写回到客户端 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;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) {// 1) 读取请求并解析DatagramPacket requestPacket new DatagramPacket(new byte[4096], 4096);socket.receive(requestPacket);// 为了方便在 java 代码中处理 (尤其是后面进行打印) 可以把上述数据报中的二进制数据, 拿出来, 构造成 StringString request new String(requestPacket.getData(), 0, requestPacket.getLength());// 2) 根据请求计算响应String response this.process(request);// 3) 把响应写回到客户端DatagramPacket responsePacket new DatagramPacket(response.getBytes(), 0, response.getBytes().length,requestPacket.getSocketAddress());socket.send(responsePacket);System.out.printf([%s:%d] req%s, resp%s\n, requestPacket.getAddress(), 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();} } 如果要写别的服务器例如翻译网站可以继承该服务器然后重写process方法在响应方面重新重写使用Map来记录key-value之间的关系 TCP TCP的socket api也有两个关键的类 ServerSocket 其中也有三个重要的方法 接听操作方法 public Socket accept() throws IOException {if (isClosed())throw new SocketException(Socket is closed);if (!isBound())throw new SocketException(Socket is not bound yet);Socket s new Socket((SocketImpl) null);implAccept(s);return s; } 构造方法 public ServerSocket(int port) throws IOException {this(port, 50, null); } 关闭资源的方法 public void close() throws IOException {synchronized(closeLock) {if (isClosed())return;if (created)impl.close();closed true;} } Socket客户端和服务器都要用两边都要用不能叫做ClientSocketTCP传输的是字节流就是传输字节传输的基本单位就是byte Socket 其中重要的方法 构造方法 public Socket(String host, int port) throws UnknownHostException, IOException {this(host ! null ? new InetSocketAddress(host, port) :new InetSocketAddress(InetAddress.getByName(null), port),(SocketAddress) null, true); } 获取socket内部持有的对象 public InputStream getInputStream() throws IOException {if (isClosed())throw new SocketException(Socket is closed);if (!isConnected())throw new SocketException(Socket is not connected);if (isInputShutdown())throw new SocketException(Socket input is shutdown);InputStream in this.in;if (in null) {// wrap the input stream so that the close method closes this socketin new SocketInputStream(this, impl.getInputStream());if (!IN.compareAndSet(this, null, in)) {in this.in;}}return in; } 获取socket内部持有的流对象 public OutputStream getOutputStream() throws IOException {if (isClosed())throw new SocketException(Socket is closed);if (!isConnected())throw new SocketException(Socket is not connected);if (isOutputShutdown())throw new SocketException(Socket output is shutdown);OutputStream out this.out;if (out null) {// wrap the output stream so that the close method closes this socketout new SocketOutputStream(this, impl.getOutputStream());if (!OUT.compareAndSet(this, null, out)) {out this.out;}}return out; } 同时还可以获得源和目的主机的信息 public InetAddress getInetAddress() {if (!isConnected())return null;try {return getImpl().getInetAddress();} catch (SocketException e) {}return null; }ServerSocket和Socket这俩起到的作用截然不同的服务器一上来要先处理客户端来的连接 Socket clientSocket serverSocket.accept(); //服务器一启动就会立即执行到这里如果客户端没有连接过来accept也会产生阻塞直到说有客户端真的连接上来了 举一个比较形象的栗子有一个西装革履的小哥来到我面前这个人不是大老板就是销售他把我领到一个地方这个地方都是西装革履的人给我介绍房子然后小哥就消失了然后由别的人带我介绍此时小哥就可以理解为ServerSocket其他带我介绍的人可以理解为clientSocket ServerScoket用于在服务器端使用的揽客 - acceptSocket用于服务器和客户端来进行通信 - getInputStream,getOutStream 相当于打电话的时候接通电话后会说很多话不是说一句就挂了 Scanner scanner new Scanner(inputStream); String request scanner.next(); //这个读取方式就是会读到“空白符”才会读取完毕如果直接按照read方式来读读出来的就是byte[]还需要转成Srting //如果直接使用Scanner的话直接读出来的就是StringScanner已经帮我们做好上述的转换操作了 //客户端在发送数据的时候无比要在每个请求的结尾填上空白符\n, \t, 回车, 换行 //上述要求属于咱们对于通信细节的约定 由于TCP上面是按照字节来传输的而是实际上我们是希望若干个字节能够构成一个“应用层数据报”如何区分从哪到哪是一个应用层数据报就可以通过“分隔符”的方式来约定上述代码就是在约定说使用空白符来作为一个请求的结束标记 从TCP socket中读出一大串字节可能会包含多个应用层的请求数据就需要作出区分 不论是发请求还是返回响应也要使用Scanner的方式来next因此就要求服务器返回的响应也要带有\n使用next读取数据如果数据中不带有\n等分隔符的话此时next就会一直阻塞Scanner是会带有阻塞功能的 if (!scanner.hasNext()) {// 如果发现后续没有数据了, 此时说明 TCP 的连接是已经断开了的.System.out.printf([%s:%d] 客户端下线!\n, clientSocket.getInetAddress(), clientSocket.getPort());break; } String request scanner.next(); 这里的scanner.hasNext就会阻塞等待请求的到达 请求到了有明确的分隔符返回truetcp连接断开了返回false scanner可以认为是关联到了服务器这边的socket文件socket是能感知到tcp断开连接的本身是系统内核里面会有一系列的流程四次挥手 操作系统知道这个事情之后就会告知socket对应的scanner读取的文件就相当于是“无效文件”类似于读取到EOF这样的效果使用scanner读文件的时候就是读到文件末尾hasNext也是会返回false一旦tcp连接断开scanner就相当于读到文件末尾的效果都是读到EOF反映到scanner上面就是hasNext为false Question hasNext方法阻塞时间长了就表名TCP连接断开了吗客户端自行断开会影响服务端吗 Answer 不是的TCP连接断开hasNext解除阻塞并返回falseTCP连接仍然存在但是对方没有发数据过来hashNext是阻塞的对方发数据过来了hasNext解除阻塞返回true在TCP中是这样的客户端断开连接服务器是能感知到的 while (true) {// 3.1 读取请求并解析if (!scanner.hasNext()) {// 如果发现后续没有数据了, 此时说明 TCP 的连接是已经断开了的.System.out.printf([%s:%d] 客户端下线!\n, clientSocket.getInetAddress(), clientSocket.getPort());break;}String request scanner.next();// 3.2 根据请求计算响应String response process(request);// 3.3 把响应写回给客户端.outputStream.write(response.getBytes(), 0, response.getBytes().length);// 3.4 服务器打印日志System.out.printf([%s:%d] req%s, resp%s\n, clientSocket.getInetAddress(), clientSocket.getPort(), request, response); } public void start() {System.out.println(客户端启动!);Scanner scanner new Scanner(System.in);try (InputStream inputStream socket.getInputStream();OutputStream outputStream socket.getOutputStream()) {Scanner scannerNetwork new Scanner(inputStream);while (true) {// 1. 从控制台读取数据System.out.print(请输入要发送的数据: );String request scanner.next();// 2. 把请求发送给服务器, 发送的请求要带有 \n, 和服务器的 scanner.next 是对应的.// 由于上述通过 next 读到的 request 本身已经没有 \n 结尾了. 需要手动添加上换行request \n;outputStream.write(request.getBytes());// 3. 从服务器读取到响应if (!scannerNetwork.hasNext()) {break;}String response scannerNetwork.next();// 4. 把响应显示到控制台上System.out.println(response);}} catch (Exception e) {e.printStackTrace();} }重点理解“客户端下线”操作当强制终止客户端进程或者通过代码调用客户端socket,close()就会使客户端所在的主机的操作系统内核触发TCP断开连接流程四次挥手服务器就能感知到于是就会在hasNext解除阻塞并返回falseif这里逻辑取反于是就进入if语句内部执行打印 下线 的操作并break了 上述代码还存在一些问题 服务器代码这边对于accept创建的socket对象是没有进行关闭操作的 Socket clientSocket serverSocket.accept(); //这个东西在processConnection中使用之后没有进行close这个是不科学的 serverSocket是可以不必特别关闭的因为生命周期是跟随整个服务器进程的客户端的socket也是可以不必特别关闭的 但是服务器的clientSocket就不行了服务器会对应多个客户端每个客户端都有一个对应的clientSocket如果用完了不关闭就会使当前clientSocket对应的文件描述符得不到释放引起文件资源泄露 try (InputStream inputStream clientSocket.getInputStream();OutputStream outputStream clientSocket.getOutputStream()) {...} catch (IOException e) {e.printStackTrace(); } finally {// 在这里关闭是比较靠谱的做法.// 即使当前 processConnection 在不同的线程中被调用, 也可以正确关闭.clientSocket.close(); } 有的时候close操作的异常也需要单独处理没啥太好的方法 当前这个代码服务器是无法同时给多个客户端提供服务端 使用service操作虽然有两个客户端了但是服务器只感知到一个客户端上线第一个客户端发来的请求能够顺利处理第二个客户端的请求就处理不了了一旦第一个客户端结束服务器就能立即感知到第二个客户端上线以及感知到客户端之前的请求并且立即返回响应 while (true) {// 3.1 读取请求并解析if (!scanner.hasNext()) {// 如果发现后续没有数据了, 此时说明 TCP 的连接是已经断开了的.System.out.printf([%s:%d] 客户端下线!\n, clientSocket.getInetAddress(), clientSocket.getPort());break;}String request scanner.next();// 3.2 根据请求计算响应String response process(request);// 3.3 把响应写回给客户端.outputStream.write(response.getBytes(), 0, response.getBytes().length);// 3.4 服务器打印日志System.out.printf([%s:%d] req%s, resp%s\n, clientSocket.getInetAddress(), clientSocket.getPort(), request, response); } 解决方案多线程 第一个客户端连接之后此时accept就返回了进入到processConnection方法就在方法内部的while循环开始循环起来了第二个客户端来了之后此时没有办法执行到第二次accept的第二个客户端给服务器打电话服务器一直没接听一方面希望给第一个客户端提供服务另一方面还能希望快速第二次调用到accept我们可以使用多线程 主线程专门负责循环的处理accept每次accept获取到一个客户端连接之后都创建一个新的线程用新的线程来给客户端循环的提供服务 public void start() throws IOException {System.out.println(服务器启动!);// 能一直扩容// 如果用固定线程个数的线程池, 不太合适, 就限制了最多有多少个客户端同时连接.ExecutorService pool Executors.newCachedThreadPool();while (true) {Socket clientSocket serverSocket.accept();// 代码改成多线程的形式, 就不能通过 try ( ) 的方式来关闭 clientSocket 了.// 否则就会使 clientSocket 被立即关闭, 此时 processConnection 还没来得及使用的. // Thread t new Thread(() - { // try { // processConnection(clientSocket); // // clientSocket.close(); // } catch (IOException e) { // e.printStackTrace(); // } // }); // t.start();// 把任务添加到线程池中pool.submit(new Runnable() {Overridepublic void run() {try {processConnection(clientSocket);} catch (IOException e) {e.printStackTrace();}}});} } 如果线程太多电脑会撑不住所以这里核心解决方案IO多路复用 多个服务器分布式系统 IO多路复用 通过AI可以知道IO多路复用是什么机制 IO多路复用是一种同步非阻塞的IO模型它允许单个线程处理多个文件描述符FD从而管理多个网络连接或IO流。这种机制使得服务器能够高效地处理大量的并发连接而不需要为每个连接创建一个独立的线程或进程。 IO多路复用主要通过三种机制实现select、poll和epoll。 select这是最早的IO多路复用机制它使用一个文件描述符集合来进行监控并通过内核检查每个FD来确定是否有事件发生。select的缺点包括对文件描述符数量有限制通常是1024以及需要在用户态和内核态之间复制文件描述符集合这会导致额外的性能开销。pollpoll是select的改进版它没有最大文件描述符数量的限制并且使用动态数组来存储FD。尽管如此poll仍然需要遍历整个FD集合来查找哪些FD已经就绪这在大量FD的情况下效率不高。epoll这是Linux特有的IO多路复用机制它比select和poll更高效。epoll使用内核事件表来管理FD并且不需要复制文件描述符集合从而减少了数据复制的开销。epoll还支持水平触发LT和边缘触发ET两种模式其中边缘触发模式可以避免大量不必要的事件通知。 IO多路复用的优势在于它能够提高单个线程处理多个IO请求的能力减少了线程创建和上下文切换的开销提高了系统的并发性能。它在网络编程中特别有用可以用于实现高性能的服务器和客户端应用程序。 在实际应用中IO多路复用可以用于网络编程、高性能服务器、文件操作和定时器事件调度等场景。例如Web服务器可以使用IO多路复用来同时处理大量并发请求而不会因为某个请求的IO操作而阻塞其他请求的执行。 总结来说IO多路复用是一种强大的技术可以在单个线程中处理多个I/O操作提高程序的实时性能特别是在处理大量数据、提高实时性能和提高系统性能方面具有非常重要的作用。 当前写的tcp server和client这里就涉及到三种socket 服务器ServerSocket服务器Socket通过这个Socket和客户端提供交互能力客户端Socket通过这个Socket和服务器进行交互 第二个socket服务器这边会有多个这样的socket每个客户端都有一个对应的socket这个socket在客户端断开连接之后就不再使用了就需要关闭掉 第一个和第三个都是生命周期跟随整个进程程序只要在运行就需要这个socket不能提前close的随着进程结束这些socket自然释放 何时关闭第二个socket这个连接用完了之后 private void processConnection(Socket clientSocket) throws IOException;此处的processConnection这个方法就表示一个客户端连接的整个处理过程这个方法执行完毕就是用完了这个方法里也是感知到客户端关闭断开连接才返回的此时就可以在这个方法的末尾进行close了 自定义应用层协议 信息确定数据的格式 基于行文本的方式来传输基于xml的方式基于jsonymlprotobuffer针对要传输的数据进行压缩虽然可读性不好但是能够把空间最充分的利用最节省网络带宽效率也最高
http://www.sczhlp.com/news/187269/

相关文章:

  • 网站开发类优惠及服务承诺学服装设计学费要多少
  • 互联网站源码网页功能介绍
  • 高端网站建设公司哪家服务态度好中小企业查询网站
  • 做电商网站微信号是多少手机网站与app
  • 怎么知道网站有没有备案重庆好网互联
  • 想学网站建设深圳代理网络推广公司
  • 成都医院做网站建设网站开发vsc网站开发公司
  • 奖励软件下载网站网站规划与设计范文
  • 酒店网站建设报告书购物商城网页模板
  • 网站转移空间WordPress主题 Slhao
  • 网站建设按什么合同交印花税旅游网络营销方式
  • 网站营销建设策划案做游戏网站用什么系统做
  • 品牌网站建设解决方电子商务公司网站怎么建
  • 阿里国际网站首页可以做全屏不咨询公司的成本费用有哪些
  • 网站建设和app哪个好深圳企业社保网站官网
  • 虚拟产品货源网站一个购物交易网站怎么做
  • 汕头企业网站建设模板小橡皮私人定制app软件
  • 深圳罗湖住房和建设局网站官网个人互动网站
  • 做网上夫妻去哪个网站互联网保险市场
  • 影盟自助网站建设祭祖网站怎么做
  • 手机网站开源系统公司注册地址与办公地址不一致
  • wordpress设置网站地址零配件加工东莞网站建设技术支持
  • 新网 网站备案做网站文字居中代码
  • 平台网站怎么做seo做服装广告素材网站有哪些
  • 南京医院网站建设方案建小公司网站
  • 电子商务系统网站建设淘宝做导航网站有哪些
  • 网站建设开发服务费会计科目开题报告风景区网站开发
  • 有利于优化的网站模板精品源码网
  • 网站建设补充报价单榆林网站建设推广
  • 顺德网站制作案例教程建设网站便宜