- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如何阻止 SocketException 的发生?
我正在尝试将序列化对象从客户端简单传输到本地计算机上的服务器。
我已经能够使用以下代码的细微变化来发送字符串,但是当我尝试发送对象时
Customer customerToReceive = (Customer) input.readObject();// EXCEPTION OCCURS RIGHT HERE
我收到一个我不明白如何解释的 SocketException。
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.read(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.read(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream.defaultReadFields(Unknown Source)
at java.io.ObjectInputStream.readSerialData(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at MattServer.runCustomerServer(MattServer.java:44)
at MattServer.<init>(MattServer.java:14)
at MattServerTest.main(MattServerTest.java:10)
这是客户端代码,它似乎根本没有提示: 公开课 MattClient { 套接字客户端; ObjectOutputStream输出; 对象输入流输入; 字符串消息;
public MattClient()
{
runCustomerClient();
}
public void runCustomerClient()
{
try
{
//Connection:
System.out.println("Attempting connection...");
client = new Socket("localhost",12345);
System.out.println("Connected to server...");
//Connect Streams:
//output.flush();
System.out.println("Got IO Streams...");
//SEND MESSAGES:
try
{
for(int i = 1;i<=10;i++)
{
output = new ObjectOutputStream(client.getOutputStream());
Customer customerToSend = new Customer("Matt", "1234 fake street", i);
System.out.println("Created customer:");
System.out.println(customerToSend.toString());
output.writeObject(customerToSend);
output.flush();
};
message = "TERMINATE";
System.out.println(message);
output.writeObject(message);
output.reset();
output.flush();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch(Exception e2)
{
e2.printStackTrace();
}
finally
{
}
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
catch(Exception e3)
{
e3.printStackTrace();
}
finally
{
}
}
反抗的服务器:
public class MattServer
{
ServerSocket server;
Socket socket;
ObjectInputStream input;
ObjectOutputStream output;
String message;
public MattServer()
{
runCustomerServer();
}
public void runCustomerServer()
{
try
{
server = new ServerSocket(12345,100000);
while(true)
{
//CONNECTION:
System.out.println("Waiting for connection");
socket = server.accept();
System.out.println("Connection received...");
//CONNECT STREAMS:
//output = new ObjectOutputStream(socket.getOutputStream());
//output.flush();
input = new ObjectInputStream(socket.getInputStream());
System.out.println("Got IO Streams...");
//PROCESS STREAMS:
System.out.println("Connection successful!");
do
{
System.out.println("Started loop");
try
{
System.out.println("in try...");
System.out.println(socket.getInetAddress().getHostName());
Customer customerToReceive = (Customer) input.readObject();// EXCEPTION OCCURS RIGHT HERE
Object o = input.readObject();
System.out.println("Object of class " + o.getClass().getName() + " is " + o);
System.out.println("Got customer object");
System.out.println(customerToReceive.toString());
}
catch(ClassNotFoundException cnfE)
{
System.out.println("Can't convert input to string");
}
} while(!message.equals("TERMINATE"));
System.out.println("Finished.");
}
}
catch(IOException ioE)
{
ioE.printStackTrace();
}
finally
{
try
{
input.close();
socket.close();
server.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
最佳答案
此异常是过早关闭连接的结果,即客户端发送了它的数据并立即关闭了连接。在这种情况下,服务器通常无法读取客户端发送的所有数据,并且在服务器端看到的传输过程中连接终止。
请注意,flush()
-ing 网络 OutputStream
并不意味着或保证任何/所有数据已实际传输。在最好的情况下,这只会确保所有数据都传递到本地计算机上的网络堆栈,这将自行决定何时实际传输数据。
对此的一种解决方案是让服务器在准备就绪时关闭连接。然后客户端应该等待,例如在阻塞的 read()
操作中,然后当 server 发出传输结束信号时,将收到指定异常的通知。
另一种方法是实现自己的确认,这样客户端将等待服务器发回确认消息,之后双方可以安全地关闭连接。
作为引用,在像您这样的情况下,有一些套接字选项会影响连接的行为,即:
(这些套接字选项不是您的问题的解决方案,但在某些情况下可能会改变观察到的行为。)
编辑:
看来 SO_LINGER
选项与观察到的行为的相关性并不像我从引用文档中所认为的那样明显。因此,我会尽量使这一点更清楚:
在 Java 中,基本上两种方法可以通过 close()
终止 TCP 连接:
没有启用SO_LINGER
选项。在这种情况下,会立即发送 TCP 连接重置 (RST
) 并返回对close()
的调用。在接收到 RST
后尝试使用连接(读取或写入)时,连接的对等方将收到一个异常,指出“连接已重置”。
使用启用 SO_LINGER
选项。在这种情况下,会生成一个 TCP FIN
以有序地关闭连接。然后,如果对等方没有在给定的时间范围内确认发送的数据,则会发生超时,并且发出 close()
的本地方会像案例 #1 一样继续,发送 RST
,然后声明连接“已终止”。
因此,通常人们希望启用 SO_LINGER
以允许对等方处理数据,然后干净地断开连接。如果 SO_LINGER
未启用并且 close()
被调用之前所有数据都已被对等方处理(即'太早') 命名的异常重新重置 连接发生在对等方。
如上所述,TCP_NODELAY
选项可能以不确定的方式改变观察到的行为,因为写入的数据更有可能已经通过网络传输在调用close()
之前导致连接重置。
关于java - 通过套接字发送对象导致 SocketException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13827625/
我的一位教授给了我们一些考试练习题,其中一个问题类似于下面(伪代码): a.setColor(blue); b.setColor(red); a = b; b.setColor(purple); b
我似乎经常使用这个测试 if( object && object !== "null" && object !== "undefined" ){ doSomething(); } 在对象上,我
C# Object/object 是值类型还是引用类型? 我检查过它们可以保留引用,但是这个引用不能用于更改对象。 using System; class MyClass { public s
我在通过 AJAX 发送 json 时遇到问题。 var data = [{"name": "Will", "surname": "Smith", "age": "40"},{"name": "Wil
当我尝试访问我的 View 中的对象 {{result}} 时(我从 Express js 服务器发送该对象),它只显示 [object][object]有谁知道如何获取 JSON 格式的值吗? 这是
我有不同类型的数据(可能是字符串、整数......)。这是一个简单的例子: public static void main(String[] args) { before("one"); }
嗨,我是 json 和 javascript 的新手。 我在这个网站找到了使用json数据作为表格的方法。 我很好奇为什么当我尝试使用 json 数据作为表时,我得到 [Object,Object]
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我听别人说 null == object 比 object == null check 例如: void m1(Object obj ) { if(null == obj) // Is thi
Match 对象 提供了对正则表达式匹配的只读属性的访问。 说明 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的
Class 对象 使用 Class 语句创建的对象。提供了对类的各种事件的访问。 说明 不允许显式地将一个变量声明为 Class 类型。在 VBScript 的上下文中,“类对象”一词指的是用
Folder 对象 提供对文件夹所有属性的访问。 说明 以下代码举例说明如何获得 Folder 对象并查看它的属性: Function ShowDateCreated(f
File 对象 提供对文件的所有属性的访问。 说明 以下代码举例说明如何获得一个 File 对象并查看它的属性: Function ShowDateCreated(fil
Drive 对象 提供对磁盘驱动器或网络共享的属性的访问。 说明 以下代码举例说明如何使用 Drive 对象访问驱动器的属性: Function ShowFreeSpac
FileSystemObject 对象 提供对计算机文件系统的访问。 说明 以下代码举例说明如何使用 FileSystemObject 对象返回一个 TextStream 对象,此对象可以被读
我是 javascript OOP 的新手,我认为这是一个相对基本的问题,但我无法通过搜索网络找到任何帮助。我是否遗漏了什么,或者我只是以错误的方式解决了这个问题? 这是我的示例代码: functio
我可以很容易地创造出很多不同的对象。例如像这样: var myObject = { myFunction: function () { return ""; } };
function Person(fname, lname) { this.fname = fname, this.lname = lname, this.getName = function()
任何人都可以向我解释为什么下面的代码给出 (object, Object) 吗? (console.log(dope) 给出了它应该的内容,但在 JSON.stringify 和 JSON.parse
我正在尝试完成散点图 exercise来自免费代码营。然而,我现在只自己学习了 d3 几个小时,在遵循 lynda.com 的教程后,我一直在尝试确定如何在工具提示中显示特定数据。 This code
我是一名优秀的程序员,十分优秀!