【问题标题】:Close socket connection after receiving stream - java接收流后关闭套接字连接 - java
【发布时间】:2013-02-27 18:02:35
【问题描述】:

我创建了一个 tcp 服务器,它从客户端获取文件名并读取位于服务器上的文件内容,然后将其流式传输回客户端。

我还做了一个客户端来接收文件。我的问题是在客户端收到文件后,如何终止循环,这样我才能关闭连接?

这是服务器代码:

import java.io.*;
import java.net.*;
import java.util.*;

public class WebTCPServer_file {
    public static void main(String argv[]) throws Exception{
        String request;
        ServerSocket welcomeSocket = new ServerSocket(6790); //opening socket
        while(true){
            Socket connectionSocket = welcomeSocket.accept();
            Scanner inFromClient = new Scanner(connectionSocket.getInputStream());
            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
            request = inFromClient.nextLine(); //client request
            System.out.println("Received: "+request);

            /*dividing request command*/
            String reqMeth = request.substring(0, 3);
            String reqURL = request.substring(5, (request.lastIndexOf("HTTP/1.1")));
            String reqProto = request.substring(request.indexOf("HTTP/1.1"));
            System.out.println("Request Method:\t" +reqMeth +"\nRequest URL:\t" +reqURL+ "\nRequest Protocol: " +reqProto);

            File localFile = new File(reqURL.trim());
            FileReader in = new FileReader(localFile);
            BufferedReader inBuff = new BufferedReader(in);


            String c;
            while((c = inBuff.readLine())!=null){                   
                outToClient.writeBytes(c + '\n');                   
                System.out.println(c);
            } //END while
            outToClient.flush();
            in.close();


        } //END while(true)
      } //END main
} //END class

这是客户端代码:

import java.io.*;
import java.net.*;
import java.util.*;
public class TCPClient_file {

    public static void main(String[] args) throws Exception{
        String sentence ;
        Scanner inFromUser = new Scanner(System.in);
        Socket clientSocket = new Socket("192.168.0.16", 6790);
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

        BufferedReader inFromServer = new BufferedReader(
                            new InputStreamReader(
                                    clientSocket.getInputStream()));

        sentence = inFromUser.nextLine();

        outToServer.writeBytes(sentence + '\n');

        String serverfile;

        while ((serverfile = inFromServer.readLine()) != null) 
            System.out.println(serverfile);

        inFromServer.close();   
        outToServer.close();
        clientSocket.close();
    }   //END main

}   //END class

来自服务器的客户端请求:

GET /domains.txt HTTP/1.1

其中“domains.txt”是服务器上包含网站列表的文件。

【问题讨论】:

  • 除非您知道文件是文本,否则不应使用 Readers 和 Writers。使用 InputStreams 和 OutputStreams:它们适用于所有文件。

标签: java sockets network-programming tcpclient tcpserver


【解决方案1】:

while 循环不会终止,因为inFromServer 期待更多数据。您需要在服务器端关闭连接(outToClient),以便客户端可以确定没有更多数据进来。

【讨论】:

  • 谢谢。就是这么简单。
【解决方案2】:

实现这一点的一个粗略方法是发送一个触发器[String from server],在将所有数据发送到客户端后,表明文件传输完成,在客户端你可以检查这个字符串,收到这个字符串后你可以退出您的 while 循环并可以关闭连接。

另一种更好的方法是,在服务器端发送实际文件内容之前发送文件的大小,然后发送实际文件数据,在客户端跟踪读取的字节,一旦你读取的字节等于之前发布的大小,您可以终止您的 while 循环

【讨论】:

  • 谢谢先生。我将在这个想法的基础上进行更复杂的文件传输。
  • 没有任何可以发送的触发器不能显示为数据,除非您开始在数据中转义它,当然当您也必须转义时。
  • @EJP 你是对的,因此只有第二种方法更好,我们还需要注意将长度与实际数据分开,基本上需要添加 header 和 payload 机制,其中 header 可以包含有效负载元数据并且有效负载本身将是实际的文件内容
猜你喜欢
  • 1970-01-01
  • 2012-02-05
  • 2011-04-26
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多