Windows和Linux之间Java套接字的差异 – 如何处理它们?
我在理解
Java如何处理Windows和
Linux上的套接字方面遇到了很多麻烦 – 特别是当其中一方(客户端或服务器)突然关闭连接时.
我编写了以下非常简单的Server和Client类,以使我的观点变得简单,客观,并且易于理解: SimpleClient.java: import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; public class SimpleClient { public static void main(String args[]) { try { Socket client_socket = new Socket("127.0.0.1",9009); // Used to read from a terminal input: BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // Used for client/server communication: BufferedReader in = new BufferedReader(new InputStreamReader(client_socket.getInputStream())); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client_socket.getOutputStream())); while(true) { System.out.print("Command: "); String msg = br.readLine(); // Send: out.write(msg); out.newLine(); out.flush(); // Receive: int ifirst_char; char first_char; if((ifirst_char = in.read()) == -1) { // Server Closed System.out.println("Server was closed on the other side."); break; } first_char = (char) ifirst_char; msg = String.valueOf(first_char); msg += in.readLine(); // Shows the message received from the server on the screen: System.out.println(msg); } } catch(Exception e) { e.printStackTrace(); } } } SimpleServer.java: import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class SimpleServer { public static void main(String args[]) { try { ServerSocket server_socket = new ServerSocket(9009); Socket client_socket = server_socket.accept(); while(true) { BufferedReader in = new BufferedReader(new InputStreamReader(client_socket.getInputStream())); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client_socket.getOutputStream())); // Receive: int ifirst_char; char first_char; if((ifirst_char = in.read()) == -1) { // Client Closed System.out.println("Client was closed on the other side."); break; } first_char = (char) ifirst_char; String msg = msg = String.valueOf(first_char); msg += in.readLine(); msg = "Server Received: " + msg; // Send: out.write(msg); out.newLine(); out.flush(); } } catch(Exception e) { e.printStackTrace(); } } } 当然,我可以实现一个代码来正确关闭客户端或服务器,但正如我所说,目标是模拟任何一方的突然关闭,不能发送或接收“断开代码”.这就是我创建这两个非常简单的类的原因. $java SimpleClient Command: echo Server Received: echo Command: test Server Received: test Command: (server now was closed on the other side) Server was closed on the other side. $ 但是在Windows上: C:simplesocket>java SimpleClient Command: echo Server Received: echo Command: test Server Received: test Command: (server now was closed on the other side) java.net.SocketException: Connection reset by peer: socket write error at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(Unknown Source) at java.net.SocketOutputStream.write(Unknown Source) at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source) at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source) at sun.nio.cs.StreamEncoder.implFlush(Unknown Source) at sun.nio.cs.StreamEncoder.flush(Unknown Source) at java.io.OutputStreamWriter.flush(Unknown Source) at java.io.BufferedWriter.flush(Unknown Source) at SimpleClient.main(SimpleClient.java:32) 假设我尝试通过修改SimpleClient.java上的以下行来忽略此异常: // Send: try { out.write(msg); out.newLine(); out.flush(); } catch(Exception e) {} 抛出另一个异常: C:simplesocket>java SimpleClient Command: echo Server Received: echo Command: test Server Received: test Command: (server now was closed on the other side) java.net.SocketException: Connection reset at java.net.SocketInputStream.read(Unknown Source) at java.net.SocketInputStream.read(Unknown Source) at sun.nio.cs.StreamDecoder.readBytes(Unknown Source) at sun.nio.cs.StreamDecoder.implRead(Unknown Source) at sun.nio.cs.StreamDecoder.read(Unknown Source) at java.io.InputStreamReader.read(Unknown Source) at java.io.BufferedReader.fill(Unknown Source) at java.io.BufferedReader.read(Unknown Source) at SimpleClient.main(SimpleClient.java:42) 我不知道代码上的相应行是否会在这些异常上指出,但是第一个抛出out.flush()而第二个抛出on.read(). 在Windows上,它在发送时抛出异常,更重要的是在接收时抛出异常 – 当调用read()方法时 – 我无法获得“流末尾”(-1)代码. 这引出了一些问题: 我试图在网上搜索这个特定主题几个小时,但没有成功. 我也尝试了许多解决方案,比如在客户端的client_socket中调用isConnected(),isBound(),isClosed()等方法,但没有成功.即使在关闭服务器之后,他们总是说有一个活动连接并且没有问题.希望有人会花时间回答这些问题中的至少一个问题. 对于任何答案,您都会提前致以最诚挚的谢意.
你的代码没有任何关闭,所以我假设你实际上意味着一个端点进程被停止,也就是被杀死.
Unix socket sd是“只是”fd的,当Unix进程结束而没有关闭fd时,包括JVM停止的情况 Windows套接字(WinSock)是与文件不同的API.如果Windows进程结束而没有调用closesocket(类似于 如果它足以处理代码错误(泄漏)和信号而不是JVM错误和失败,那么你可以只是Socket的子类 在Unix或Windows套接字中,收到的FIN被视为文件结束,就像任何其他文件一样,例如磁盘文件. 如果您还考虑对等系统出现故障(不仅仅是JVM)或网络某些部分出现故障的情况, 旁白:服务器应该在不在while(true)do-a-line循环内部之前创建BufferedReader;如果您曾经/希望一次发送多行的客户端,则显示的代码将丢失数据.如果first_char == – 1,则不需要该头发,否则转换为String;只需使用in.readLine,它就会完全返回null初始in.read返回-1的情况相同,这是(TCP)Socket在收到FIN时的情况.相反,应检查来自System.in的客户端readLine;如果有人输入^ Z或^ D或任何你会得到NPE. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 在win10环境下搭建 solr 开发环境
- 如何在内存/ CPU时间有限的Windows下运行程序?
- windows – 在Win32应用程序中模仿丙烯酸
- windows-runtime – WinRT Xaml Toolkit列系列错误?
- windows – 什么wmi计数器可以指示端口耗尽
- windows-7 – Windows 7 VPN是否可与Cisco ASA 5510配合使用
- 在Windows 8上安装mongodb作为服务
- MinGW x64 for Windows安装
- windows – 你不觉得编写安装程序可能/应该更简单吗?
- windows-server-2012-r2 – Server 2012 R2中NIC组合的最佳