但是,如果我希望服务器能够始终保持活力,即使客户端死亡,该怎么办呢?我希望能够恢复断开的连接.
回声服务器:
import java.net.Socket; import java.net.ServerSocket; public class EchoServer { public static void main(String[] args) throws Exception { // create socket int port = 4444; ServerSocket serverSocket = new ServerSocket(port); System.err.println("Started server on port " + port); // repeatedly wait for connections,and process while (true) { // a "blocking" call which waits until a connection is requested Socket clientSocket = serverSocket.accept(); System.err.println("Accepted connection from client"); // open up IO streams In in = new In (clientSocket); Out out = new Out(clientSocket); // waits for data and reads it in until connection dies // readLine() blocks until the server receives a new line from client String s; while ((s = in.readLine()) != null) { out.println(s); } // close IO streams,then socket System.err.println("Closing connection with client"); out.close(); in.close(); clientSocket.close(); } } }
任何提示赞赏谢谢
解决方法
> src addr
> src端口
> dest addr
>目的港
>和消息有效负载本身
>和其他一些东西(比如序列计数器,以确保’数据包’在传输过程中不会混乱)
服务器的操作系统使用src / dest addr / port信息来判断这是否是“正在进行的对话”.主要是它认为dest端口(因为消息已经通过互联网和防火墙将其发送到机器本身)来决定它是否适合用于监听’dest端口’的Java程序.但是,它使用整个src-addr / src-port / dest-addr / dest-port尝试按发送方发送的顺序将有效负载传送到您的程序(这可能不是它们到达的顺序,因为干预互联网).请注意,单个“消息”实际上可能会拆分为多个数据包.您的操作系统的TCP / IP堆栈正在为您做一些工作.
但是,请注意,为了代表您执行此功能,操作系统必须投入一些资源来“跟踪TCP / IP会话的状态”.至少,对于每组port / addr src / dest,需要有一个最后收到的“数据包”的计数器,一些缓冲空间来保存数据包直到你的程序准备好消耗它们,所以向前.
现在,TCP / IP堆栈实现者所面临的问题是“我应该在多长时间内保持这种状态”?足够10秒? 20分钟?在某些时候,在没有从客户端听到一段时间后,会话必须“超时”.如果序列中有更多的数据包要发送,并且客户端再次开始发送它们,那么服务器必须能够说“对不起,你发送了一些先前消息的数据包234,但因为我没有收到来自你有一段时间了,我丢掉了1-233包.我们可以重新开始吗?“
所以从这个意义上说,没有办法阻止客户端“断开连接”.当然,如果客户端恢复并发送更多数据,您可以继续监听套接字.但是你和你的客户需要一种方法来“选择我们离开的地方”.
在HTTP中,这是使用’会话cookie’实现的 – 一个服务器提供给客户端的长唯一字符串,客户端重新发送每个新请求(无论它是否发生在同一个TCP级会话上).这是一个“应用程序级会话”,其生命周期比TCP会话的生命周期长.
既然你正在编写一个应用程序,听起来你对客户端和服务器之间的相互控制权(“协议”)有一定程度的控制权,那么你可以选择更多关于如何就什么是会话,如果客户’消失'(会话超时),以及双方如何恢复并“从我们中断的地方继续”(重新建立会话)如何处理事情.你不要忘记身份验证!
正如其他人所说,这在很大程度上取决于你想要实现的目标.