java - 套接字编程:客户端断开连接使服务器挂起
问题描述
我正在尝试构建一个示例 TCP 转发器。以下是简要的功能:
- 转发器将侦听给定端口。
- 它包含客户端到服务器的映射
- 客户端将连接到转发器,转发器将查找地图并创建 2-way-forwarding-connection。
- 为此,它为每个客户端创建两个线程。
- 线程 1:从客户端读取并写入目标服务器
- 线程 2:从目标服务器读取并写入客户端。
所有这些都是用 C 编写的。客户端和目标服务器可以用任何语言编写,现在是 Java。
当我第一次运行客户端时,它按预期工作。但是,如果我终止客户端并重新启动它,服务器将永远不会收到新连接。
这是我怀疑是错误的服务器代码。
Socket clientSocket = serverSocket.accept();
InputStream inputStream = clientSocket.getInputStream();
OutputStream outputStream = clientSocket.getOutputStream();
while (true) {
byte[] bArray = new byte[2048];
try {
System.out.println(String.format("SERVER:%s: Attempting to read", this.name));
inputStream.read(bArray);
System.out.println(String.format("SERVER:%s: Received %s", this.name, new String(bArray)));
byte[] bytes = (name + ":" + counter).getBytes();
counter++;
outputStream.write(bytes);
System.out.println(String.format("SERVER:%s: Sent %s", this.name, new String(bytes)));
} catch (IOException e) {
System.out.println(String.format("SERVER:%s: Client Disconnected ", this.name));
clientSocket = serverSocket.accept();
inputStream = clientSocket.getInputStream();
}
}
在 C 程序中,我检测到断开连接并关闭套接字,如下所示:
LOGINFO("Reading from Client Socket.");
iResult = read(readSocket, buff, recvbuflen);
if (iResult <= 0) {
LOGERROR("Receiving failed");
close(readSocket);
break;
}
解决方案
你应该使用
shutdown(socket_fd, SHUT_WR);
而不是close(socket_fd)
为了正确关闭套接字。
如果您使用 SHUT_WR,则会向另一端发送一个 FIN 数据包,通知他们我们没有更多数据要发送。
推荐阅读
- asp.net-identity - 使用 Identity Server 4.1 配置 ASP.NETCore Identity
- mysql - 无法在 Ubuntu 20.04 mysql cli 8 中启用 VI 输入行编辑模式
- java - 如何编写 HQL 查询?
- javascript - 使用带有 Leaflet 地图的 GeoJSON 来给出国家边界
- python - 从 .env 文件中读取 Heroku 托管的 discord.py 机器人令牌的问题
- pandas - Pandas DateTimeIndex 产生浮点数而不是整数
- unity3d - 至于区域内的随机位置
- r - 如何确定所选点是在陆地上还是水上?
- android - Android-10 DeepLink 不工作,但在 android 10 版本以下工作
- c# - 时间格式识别与转换