在TCP协议中,如果发送端(客户端)关闭了,那么接收端(服务器端)端就会收到这个消息。

那么接收端(服务器端)怎么知道的呢?

我们进行实验:

首先在发送端中编写一段程序,当用户输入“end”的时候,关闭发送端。

import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner; public class TCP_Send {
public static void main(String[] args) throws Exception {
//TCP使用的是Socket
Socket s = new Socket("127.0.0.1",8989); OutputStream ops = s.getOutputStream(); Scanner sc = new Scanner(System.in);
while (true){
String str = sc.next();
if(str.equals("end"))
break;
ops.write(str.getBytes());
}
s.close();
}
}

接收端(服务器端)与上一章最后所示一样。

重复代码
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; public class TCP_Receive {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(8989); Socket clinet = ss.accept();//会暂停,等待连接! InputStream input = clinet.getInputStream(); byte[] buf = new byte[1024];
while(true){
int length = input.read(buf);
System.out.println(new String(buf,0,length));
} // clinet.close();
// ss.close();
//输入输出流,Socket会自动帮我们关闭
}
}

然后分别运行接收端、发送端。

接收端(服务器端)报出上面异常。

于是我们开始分析错误的原因

根据提示提示最下面一行找到了错误(一般错误/异常最下面一行就是我们自己写的代码,上面的都是系统代码不会有错的)

System.out.println(new String(buf,0,length));

然后分析这一行的错误,我们往上一层查找。

发现错误原因是这一行代码

checkBoundsOffCount(offset, length, bytes.length);

即:参数超出正常范围。

经过查找,我们发现length是-1,导致的错误。

也就是说,在我们编写的这行代码中,当流读取完了的时候,(发送端关闭的时候,这个流的生命也就走到尽头了)

int length = input.read(buf);

返回值为-1

大家可以复习一下InputStream的知识

也就是说,我们可以将read返回值是否为-1作为发送端(用户端)是否关闭的信号。

这就回答了文章开头所提的问题。

任务:当发送端关闭时,接收端也自动关闭

思路:增加一个判断,当length==-1时,跳出死循环,调用close()。又或者直接在while中判断即可

接收端(服务器端):

import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; public class TCP_Receive {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(8989);
Socket clinet = ss.accept();//会暂停,等待连接!
InputStream input = clinet.getInputStream();
byte[] buf = new byte[1024]; int length = -1;
while((length = input.read(buf))>=0){
System.out.println(new String(buf,0,length));
} clinet.close();
ss.close();
//输入输出流,Socket会自动帮我们关闭
}
}

效果:

当输入end后,服务器端、客户端双双关闭

这就是TCP协议的好处

TCP协议中,接收端知道发送端什么时候关闭。

UDP协议中,接收端和发送端相互不知道对方的情况。

【Java】学习路径57-TCP协议客户端与服务器端的关闭的更多相关文章

  1. Java学习路径及练手项目合集

    Java 在编程语言排行榜中一直位列前排,可知 Java 语言的受欢迎程度了. 实验楼上的[Java 学习路径]中将首先完成 Java基础.JDK.JDBC.正则表达式等基础实验,然后进阶到 J2SE ...

  2. Java学习路径(抛光砖)

    这就是我刚刚在五孔问答中找到的Java学习路线图抛光砖价格.我个人认为,这条Java学习路线是可以的.它是2018年相对较新的Java学习路线,更符合企业就业标准. Java学习路径的第一阶段:Jav ...

  3. TCP/IP详解学习笔记(9)-TCP协议概述

    终于看到了TCP协议,这是TCP/IP详解里面最重要也是最精彩的部分,要花大力气来读.前面的TFTP和BOOTP都是一些简单的协议,就不写笔记了,写起来也没啥东西. TCP和UDP处在同一层---运输 ...

  4. Java学习路径:不走弯路,这是一条捷径

    1.如何学习编程? JAVA是一种平台.也是一种程序设计语言,怎样学好程序设计不只适用于JAVA,对C++等其它程序设计语言也一样管用.有编程高手觉得,JAVA也好C也好没什么分别,拿来就用.为什么他 ...

  5. http协议客户端向服务器端请求时一般需要发送的内容

    out.println("GET /shopping/index.html HTTP/1.1");//请求行 包括请求方式,文件路径, http协议版本(必写)请求头.... ou ...

  6. 基于TCP的客户端、服务器端socket编程

    一.实验目的 理解tcp传输客户端服务器端通信流程 二.实验平台 MAC OS 三.实验内容 编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址.端口号,并 ...

  7. 基于TCP的客户端和服务器端的代码设计

    实验平台 linux 实验内容 编写TCP服务器和客户端程序,程序运行时服务器等待客户端连接.一旦连接成功,服务器显示客户端的IP地址和端口号,并向客户端发送字符串 实验原理 TCP是面向连接的通信, ...

  8. Java学习路径

    -------第一部分:基础语法-------- 1.输出语句 1.1 hello world 1.2 拼接输出.换行和不换行输出 1.3 拼接变量输出 2.输入语句: 2.1 定义变量,赋值(整数. ...

  9. java网络编程,简单的客户端和服务器端

    1.服务器端 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import ...

随机推荐

  1. HashMap高阶用法,十倍提升开发效率

    HashMap在工作中使用非常频繁,其实在JDK1.8的时候新增一些更高阶的用法,熟练使用这些方法可以大大提升开发效率,写出更简洁优美的代码. 1. get方法指定返回默认值(getOrDefault ...

  2. ssh-配置及使用

    ssh配置文件 SSH的配置文件在/etc/ssh/目录下     openssh-client安装后,生成的配置文件为ssh_config,主要用于连接其他linux主机时,加载此文件     op ...

  3. Contest

    Contest 题目 链接 题目描述 \(n\) 支队伍一共参加了三场比赛. 一支队伍 \(x\) 认为自己比另一支队伍 \(y\) 强当且仅当 \(x\) 在至少一场比赛中比 \(y\) 的排名高. ...

  4. HelloWord程序代码的编写和HelloWord程序的编译运行

    1.新建文件夹,存放代码 2.新建一个Java文件 文件后缀名.java(Hello.java) 3.编写代码public class Hello{public static void main(St ...

  5. 记一次 .NET 某电厂Web系统 内存泄漏分析

    一:背景 1. 讲故事 前段时间有位朋友找到我,说他的程序内存占用比较大,寻求如何解决,截图就不发了,分析下来我感觉除了程序本身的问题之外,.NET5 在内存管理方面做的也不够好,所以有必要给大家分享 ...

  6. 从编译器对指令集的要求看API设计原则

    摘要:最近看<计算机体系结构:量化研究方法(第五版)>,发现指令集设计中的一些原则,对API设计也同样适用,给大家分享一下. 本文中的所有内容来自工作和学习过程中的心得整理,如需转载请注明 ...

  7. angular里forwardRef的原理

    一段会报错的angular代码 @Injectable() class Socket { constructor(private buffer: Buffer) { } } console.log(B ...

  8. 关于Google词向量模型(googlenews-vectors-negative300.bin)的导入问题

    起因 项目中有如下代码: word2vec = KeyedVectors.load_word2vec_format('./GoogleNews-vectors-negative300.bin', bi ...

  9. C# 虚方法、抽象方法

    一.虚方法(virtual) 作用:当有一个定义在类中的函数需要在继承类中实现时,可以使用虚方法. 示例: class Person { public virtual void XXX() { Con ...

  10. LabView、CVI、MeasurementStudio三者之间的区别

    LabView是NI公司傻瓜化的图形操作测试开发工具: CVI是NI公司C语言风格的测试开发语言,当然也是工具: Measurement Studio是面向一直使用微软开发工具如VC.C#的那些开发人 ...