| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> TCP流套接字编程 -> 正文阅读 |
|
[网络协议]TCP流套接字编程 |
目录 那么问题来了,为什么我们前面写的有关UDP版本的程序没有关闭呢? 一、TCP的套接字API和UDP是完全不同的ServerSocket,是给服务器使用的 它里面有一个accept方法,这个方法和TCP“有连接”这样的特性密切相关 举个例子: 现在A(客户端)给B(服务器)打电话,A先拨号,会发出“嘟嘟嘟”的提示音,紧接着B这边就会响铃,只有B这边接通电话,A和B才能通信。 而accept就是接电话这个动作 注意由于socket是对应到文件的,所以也会有一个close方法 我们在之前写的博客中提到过,打开一个文件要及时关闭,如果不及时关闭的话,就有可能造成文件资源的泄露,最终导致后面要打文件的话就打不开了。 那么问题来了,为什么我们前面写的有关UDP版本的程序没有关闭呢?原因是: 一个socket理论上用完了之后是要关闭的,但是我们前面写的有关UDP版本的程序里面的UdpServer和UdpClient里面的socket生命周期,都是要跟随整个程序的。 注意这里还有要注意的一点是即使是socket或者是文件没有关闭,但是只要进程一结束,对应的资源自然而然也就释放了。这里的资源指的是文件描述符,文件描述符在文件描述符表里,文件描述符表在PCB里,如果进程销毁了,对应的PCB也就没了。 Socket,给客户端使用的 TCP socket是面向字节流的,因此在进行读写数据的时候,和我们之前读写文件是类似的,也是使用InputStream和OutputStream。 二、使用TCP socket写一个回显程序即写一个回显服务器和一个回显客户端,实现的功能和前面写的一样,只不过前面利用的是UDP socket,而我们这次则是使用TCP socket来实现。 服务器代码
客户端代码
客户端和服务器程序,一般都是先启动服务器,后启动客户端,这里的服务器就好比餐馆,客户端就好比要吃饭的我们,只有餐馆开门了,我们才能进去吃。 写完代码后,先运行服务器,然后运行客户端,得到的界面是 服务器和客户端的具体执行流程说的不是很准确,就是为了看的时候有个大概的思路 现在我们梳理一遍服务器和客户端它们的交互过程究竟是怎么样的,我们一步步走一遍 ?? 梳理清楚后,我们开始往客户端输入数据,得到的结果是 对出现问题的具体解决措施此时我们发现我们在客户端发送的数据,在服务器这边没有反应,而且服务器这边也没有把响应发送回客户端 此时我们对问题的猜测是 要么客户端没有正确发送数据 要么服务器没有正确读取数据 在服务器、客户端程序中,我们经过检查发现没有问题,因此推断应该是输入输出格式的问题 我们把客户端程序画圈这里的print改为println ?然后再次输入hello 得到的结果和原来一模一样 我们继续分析,这次通过添加打印的方式来检查问题 首先我们在客户端的程序中添加打印 运行程序得到的结果是 结果仍然不对 接下来我们在服务器中添加打印 运行程序得到的结果是 结果仍然错误,不过我们通过两次添加打印,我们知道了服务器在这里阻塞着 可能的原因是 1.客户端没有真正发送出数据 2.客户端这边数据发送出去了,但服务器这边因为数据格式的问题(比如空白符导致scanner.next()不能返回) 那么到底是什么原因呢 我们可以通过抓包工具来分析。 那么什么是抓包工具呢? 我们这里拓展一下,所谓的抓包工具就是一种特殊的工具可以监测到网卡上的数据是怎么走的,客户端有没有发出数据,用抓包工具一看就能看出来。如果客户端真的发了数据了,那么在抓包工具中是能抓到这个数据的。如果客户端没有真的发数据,那么抓包工具是抓不到的。 TCP的抓包工具主要有两个:tcpdump(linux的抓包工具),wireshark(是一个跨平台、图形化的抓包工具) 可以在应用市场里面直接下wireshark,下完后会显示这么一个页面 这些是当前机器上的“网络接口”,是网卡或者是虚拟网卡,我们要进行选择 如果数据走的是有线网,那么就选以太网(当然,我们这个页面没有,应该是真的有线网的话才有这个选项) 如果数据走的是无线网,那么就选WLAN 如果数据走的是127.0.0.1环回ip,就选Adapter for loopback 当前我们是用的是环回ip,因此我们选Adapter for loopback,选完之后,我们需要设置一个过滤器,抓取我们想要的数据,最简单的办法是按照端口号来过滤,即只要端口号为9090的数据。 我们先分析这个页面 ? 这个图上的数据代表的是端口号为61107的进程和端口号为61106的进程之间的数据交流。 另外我的wireshark打开选中Adapter for loopback之后,是这个页面, 然后我们先后打开服务器程序和客户端程序,然后再观察wireshark的变化 这么多的数据包该怎么办呢,此时我们可以在这里先写tcp.port==9090,然后回车 我们发现只剩三行了,而这三行正是tcp三次握手的过程 61439是客户端的端口号,9090是服务器的端口号 接下来我们在客户端的输入框中输入hello,此时没任何反应 ? 看wireshark也没有反应,没有新的数据包出现 通过抓包,我们知道了是客户端没发送成功的问题 后面经过研究发现,我们没有发送成功的原因有两点: 1.进行发送的时候,没有加ln,此时,next很可能是无法直接返回的 2.发送的时候加flush刷新缓冲区,否则数据并没有真的通过网卡来发送 在经过上述的修改后,我们发现服务器显示正常了,但是客户端显示仍旧那样,又经过像修改客户端的代码一样修改服务器的代码后,客户端这边也正常了。 修改的代码是 客户端 服务器 经过修改后的代码运行结果为 修改完代码后,输入hello,回车,我们发现显示正常了,也就是服务器和客户端都有反应了 我们再观察wireshark,发现不仅有了三次握手的过程,还有了新的数据包 ? ? 在后面的学习中,我们用的wireshark不多,用的另一个抓包工具会很多,它叫做fiddler,是专门抓http协议的数据包的。 现在的我们只是一个客户端和服务器通信,在实际的开发中,一个服务器应该要对应很多个客户端,甚至是成千上万个客户端, 对阻塞的认识在网络通信程序中,涉及到很多的“阻塞”这样的情况,这些阻塞,其实是客户端和服务器之间流程的交替。 另外,我们前面也学过多线程、锁也会导致阻塞,一旦阻塞,就意味着线程要被挂起(放到等待队列中,等时机成熟了,才能被唤醒,然后进一步的往下执行,而等待和唤醒则取决于系统的调度),一旦出现阻塞,那么整个程序的效率就会收到很大的影响。 在进行IO处理中,很多时候的确会产生阻塞(阻塞等待的过程是无法避免的),因为服务器是不知道客户端什么时候发送请求的。 那么在实际的开发中,要提高这种程序的效率,该如何做?答案是没有办法解决阻塞等待,但是可以在程序阻塞等待的过程中干点其它的事。 三、总结套接字~在TCP版本的套接字API中 ServerSocket:服务器这边使用的 Socket:客户端和服务器都需要使用 对服务器来说:1.创建ServerSocket关联上一个端口号,称为listenSocket(作用是在场外拉客) 2.调用ServerSocket的accept方法 ? ? ? ? accept的功能是把一个内核建立好的连接拿到代码中处理 ? ? ? ? accept会返回一个Socket实例,称为clientSocket(在内场负责给客户提供具体的服务) 3.使用clientSocket的getInputStream和getOutputStream得到字节流对象,然后就可以进行读取和写入了。 4.当客户端断开连接之后,服务器要及时地关闭clientSocket,否则可能会出现文件资源泄露的情况。 对客户端来说:1.创建一个Socket对象,创建的同时指定服务器的ip和端口(这个操作会让客户端和服务器建立TCP连接,连接的过程为“三次握手”,这个流程是内核完成的,我们感知不到) 2.客户端通过Socket对象的getInputStream和getOutputStream和服务器进行通信。 |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 21:35:09- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |