这个简单的Java TCP服务器/客户端示例有什么问题?
首先,启动服务器:
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws Throwable {
ServerSocket ss = new ServerSocket(2345);
Socket s = ss.accept();
OutputStream os = s.getOutputStream();
Thread.sleep(5000);
for (int i = 0; i < 3; i++) {
os.write("A".getBytes());
os.flush();
System.out.println("Written in cycle " + i);
}
os.close();
s.close();
}
}
启动客户端并在此之后观察服务器:
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Throwable{
Socket s=new Socket("localhost",2345);
s.close();
System.out.println("Closed");
}
}
客户端套接字立即关闭。 但是,服务器上的套接字写操作在第二个循环中失败,即第一次写操作不会抛出异常。
这是服务器的执行输出:
Written in cycle 0
Exception in thread "main" java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:124)
at Server.main(Server.java:16)
答案 0 :(得分:2)
您的客户端连接并立即关闭。这是由拒绝写入“无处”的服务器检测到的。
答案 1 :(得分:2)
以下链接与问题100%相符并解释问题所在以及如何解决:
http://download.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html
因此,为了更具体地与上述代码相关,将LINGER设置为0将解决问题:
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Throwable {
Socket s = new Socket("localhost", 2345);
s.setSoLinger(true, 0);
s.close();
}
}
答案 2 :(得分:1)
写入套接字时,必须将该数据传递给远程系统。如果要等待远程系统等待确认每一段数据,它会慢很多倍。无论如何,这不是TCP的工作方式。
如果您需要远程套接字来确认它已收到您的数据,您需要添加自己的协议以确保您收到的每一条数据都已收到。
答案 3 :(得分:0)
在回答您的问题时从评论中复制。
客户端套接字是否必须执行某些操作才能从服务器接收输出流?也许我只是遗漏了一些东西,所以如果我错了请纠正我,但为什么在创建后立即关闭客户端套接字?这就是问题所在。