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

北京已经开始二次感染了山东济南seo整站优化公司

北京已经开始二次感染了,山东济南seo整站优化公司,广告设计公司属于什么行业,自己怎么做彩票投注网站写在前 这一节的内容首先是对十五弹(UDP回显服务器)进行简单的改进,在这基础上开始介绍TCP流套接字编程。 目录 写在前 1.改进回显服务器 1.1完整代码实现 1.2运行输出结果 2.TCP流套接字编程 2.1ServerSocketAPI 2.2SocketAPI 3.TC…

写在前

这一节的内容首先是对十五弹(UDP回显服务器)进行简单的改进,在这基础上开始介绍TCP流套接字编程。

目录

写在前

1.改进回显服务器

1.1完整代码实现

1.2运行输出结果

2.TCP流套接字编程

2.1ServerSocketAPI

2.2SocketAPI

3.TCP版本的回显服务器

3.1代码实现

3.1.1服务器端完整代码

3.1.2客户端完成代码

3.2TCP中的长短连接

3.3解决C10M问题


1.改进回显服务器

上一节中的回显服务器,缺少业务逻辑,这里我们对代码进行改进,实现一个查词典的功能

1.1完整代码实现

这里需要的是需要重写一下process方法!

package network;import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;/*** Created with IntelliJ IDEA.* Description:* User: 苏西西* Date: 2023-10-19* Time: 21:55*/
//对于DictServer来说,和EchoServer相比大部分东西都是一样的,继承复用原来的代码
//主要是根据请求计算响应这个步骤不太一样
public class UdpDictServer extends UdpEchoServer{private Map<String,String> dict = new HashMap<>();public UdpDictServer(int port) throws SocketException {super(port);//给这个dict设置一下内容dict.put("cat","小猫");dict.put("dog","小狗");dict.put("pig","zyt");//可以无限多设置}@Overridepublic String process(String request){//查词典return dict.getOrDefault(request,"查不到!");}public static void main(String[] args) throws IOException {UdpDictServer server = new UdpDictServer(4000);server.start();}
}

1.2运行输出结果

2.TCP流套接字编程

TCP并不需要一个类来表示“TCP”数据报。

TCP不是以数据报为单位进行传输的,是以字节的方式,流式传输的。

2.1ServerSocketAPI

ServerSocket 专门给服务器使用的Socket对象。

ServerSocket构造方法
方法签名方法说明

ServerSocket(int port)

这里的port指的是服务器要绑定的端口。

创建一个服务端流套接字Socket,并绑定到指定端口。
ServerSocket方法
方法签名方法说明
Socket accept( ) 开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待
void close()关闭套接字

这里,accept() 类比于接电话;返回一个服务端Socket对象:接电话后会返回一个Socket对象,通过这个socket对象和客户端进行沟通。

2.2SocketAPI

Socket 既会给客户端使用,也会给服务器使用。

在服务器这边,是由accept返回的;在客户端这边,代码构造的时候指定一个IP和端口号(此处值指的是服务器的IP和端口),有了这个信息就可以和服务器建立连接了。

Socket构造方法
方法签名方法说明
Socket(String host,int port)创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接。
Socket方法
方法签名方法说明
InetAddress getInetAddress()返回套接字所连接的地址

InputStream getInputStream()

返回此套接字的输入流
OutputStream getOutputStream()返回此套接字的输出流

进一步通过Socket对象,获取到内部的流对象,借助流对象来进行发送/接收。

3.TCP版本的回显服务器

3.1代码实现

3.1.1服务器端完整代码

package network;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoServer {private ServerSocket serverSocket = null;public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器!");while (true){//使用这个clientSocket和具体的客户端进行交流。Socket clientSocket = serverSocket.accept();processConnection(clientSocket);}}//使用这个放方法来处理一个连接。//这一个连接对应到一个客户端,但是这里可能会涉及到多次交互。private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客户端上线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());//基于上述socket对象和客户端进行通信try(InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {//由于要处理多个请求和响应,也是使用循环来进行的while (true){//1.读取请求Scanner scanner = new Scanner(inputStream);if (!scanner.hasNext()){//如果没有下一个说明读完了,客户端关闭了连接System.out.printf("[%s:%d] 客户端下线\n!",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}//注意:此处使用的next是一直读取到换行符/空格/其他空白符结束//最终返回结果里不包含上述空白符String request = scanner.next();//2.根据请求构造响应String response = process(request);//3.返回响应结果//对于OutputStream 没有write String这个功能,可以把String里的字节数组拿出来,进行写入;//也可以用字符流来转换一下PrintWriter printWriter = new PrintWriter(outputStream);//此处使用println来写入,让结果中带有一个\n换行,方便对端(接收端)接收解析printWriter.println(response);//flush用来冲刷缓冲区,保证当前写入的数据确实发送出去了printWriter.flush();//打印一个日志System.out.printf("[%s:%d] req:%s;resp:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);}} catch (IOException e) {e.printStackTrace();}finally {//更合适的做法是将close放到finally里面,保证close()一定会被执行到try {clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(1111);server.start();}}

这里的accept() 效果是“接收连接”,前提是得有客户端来建立连接。客户端在构造Socket对象的时候就会指定服务器的IP和端口,如果没有客户端来连接,此时的accept就会阻塞。


TCP socket里面涉及两种socket对象。

这个代码中,用到了一个clientSocket,此时任意一个客户端连上来都会返回/创建一个Socket对象。(Socket就是文件)每次创建一个clientSocket对象就要占用一个文件描述符表的位置。

因此在使用完毕之后,就需要进行“释放”。

在前面的记录中,socket都没有释放,一方面这些socket生命周期更长(跟随整个程序),另一方面这些socket也不多,固定数量。

但是此处的clientSocket数量多,每个客户端都有一个,生命周期也更短。

3.1.2客户端完成代码

package network;import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoClient {//当前这里的socket既给服务器用,又给客户端用,private Socket socket = null;public TcpEchoClient(String serverIp,int serverPort) throws IOException {//Socket构造方法能够识别点分十进制格式的ip地址,比DatagramPacket更方便//new这个对象的同时,就会进行Tcp连接操作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){//1.先从键盘上读取用户输入的内容System.out.print(" >");String request  = scanner.next();if(request.equals("exit")){System.out.println("goodbye");break;}//2.把读到的内容构造成请求,发送给服务器PrintWriter printWriter = new PrintWriter(outputStream);printWriter.println(request);//此处加上flush,保证我们的数据确实发送出去了printWriter.flush();//3.读取服务器的响应,Scanner respScanner = new Scanner(inputStream);String response = respScanner.next();//4.把响应的内容给显示到界面上System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1",1111);client.start();}
}

这个对象的构造过程,就是触发TCP建立连接的过程(打电话就开始拨号了),如果客户端没有这个代码,服务器就会在accept这里阻塞,无法产生出clientSocket了。

outputSteam相当于是​对应着一个文件描述符表(socket文件),通过outputStream就可以往这个文件描述符表中写数据。

outputStream自身的方法不便写字符串,把这个流转换一下,用一个PrintWrite对象来表示(对应的文件描述符表还是同一个)

使用PrintWrite写和OutputStream写,是往同一个地方写,只不过写的过程更方便了。

3.2TCP中的长短连接

TCP发送数据时,需要先建立连接,什么时候关闭连接,就决定是短连接还是长连接。

(1)短连接:客户端每次给服务器发消息,先建立连接,发送请求,读取响应,关闭连接。下次再发送,则重新建立加连接。

(2)长连接:客户端,建立连接之后,连接不着急断开,然后再发送请求,读取响应​​​​;若干轮之后,客户端确实短时间内不再需要这个连接了,此时就断开。

服务器这里的开发很少有不用多线程的情况(当然也有用多进程的)。

这里就可以对代码进行改进:

使用多线程版本处理程序,最大的问题就是可能会涉及到频繁的申请释放线程。

在多线程的基础上,使用线程池进行代码编写。

但是如果客户端非常多,而且客户端还迟迟不断开的高压,就回导致机器上会有很多线程。此时就就会提起一种方法:增加机器。但是这就意味着需要增加成本,需要多花钱,这里的问题又被称为是C10M问题。

3.3解决C10M问题

C10K问题:单机处理1W个客户端。

C10M问题,单机处理1kw个客户端(针对多线程的版本,最大的问题就是机器承担不了这么大的线程开销,是否有办法一个线程,处理很多个客户端连接?)

IO多路复用/IO多路转接

给这个线程安排个集合,这个集合就放了一堆连接,线程就负责监听这个集合,这里的哪个连接有数据来,线程就处理哪个连接。虽然连接有很多,但是这些连接的请求并非严格意义的同时,总还是有先后的。

在操作系统中提供了一些原生的API select、poll、epoll 在Java中提供了一组NIO 这样 类,就封装了上述多路复用的API。

这一节和前一节的内容主要介绍的就是Udp和TcpSocket编程,需要注意的是,关于有无连接、面向字节流还是数据报以及全双工与否,这些特点在代码中都是有体现的。关于时候是可靠传输这一特点是隐藏在TCP背后,从代码的角度是感受不到的。TCP诞生的初心也就是为了解决可靠传输的问题。

下一部分将介绍网络原理知识的相关内容。

继续加油哦!

http://www.fp688.cn/news/156182.html

相关文章:

  • 做网站会提供源代码吗搜索百度
  • 最差网站设计网站搜索工具
  • 重庆欧勒精细陶瓷有限公司网站策划书廊坊seo整站优化
  • 用几个域名做网站好哪家网站优化公司好
  • 佛山做网站公司有哪些建站seo推广
  • 58黄页网推广效果怎样湖南关键词优化推荐
  • phpcms 怎么做网站拼多多代运营公司十大排名
  • 网站外链怎么做如何做好平台推广
  • 谷歌镜像网站怎么做珠海seo排名收费
  • 捡个杀手做老婆全集免费网站北京网站建设制作公司
  • 广东网站建设开发3seo
  • 博物馆网站建设经费请示合肥网站快速排名提升
  • 适合女生的长久职业seo薪酬
  • 为什么要建设就业指导网站本周国内重大新闻十条
  • 网站的建设与管理系统怎么做好网络营销推广
  • 政府网站 建设汇报东莞做一个企业网站
  • 征婚网站上拉业务做恒指期货域名seo站长工具
  • 政府网站建设服务淘宝宝贝关键词排名查询工具
  • 找个兼职做网站的广州网站优化公司排名
  • 信阳网站建设免费放单平台无需垫付
  • 百度卖货平台云seo
  • 网站开发 都包含什么语言网上营销怎么做
  • 如何建设学校的微网站首页百度seo排名优化公司哪家好
  • 如何建购物网站百度人工客服24小时
  • 校园门户网站开发需求分析搜索引擎费用
  • 下载了网站源码企业宣传方式有哪些
  • java 网站开发 源代码百度竞价推广怎么收费
  • 中小企业一站式服务平台crm系统成功案例分享ppt
  • 网站可以做软件检测吗信息流广告投放工作内容
  • 网站 备案 多久seo是什么缩写