【问题标题】:Java TCP server received every line from Client when all of them are sentJava TCP服务器从客户端收到所有发送的每一行
【发布时间】:2012-06-29 21:14:58
【问题描述】:

我写了两个小的java程序:一个从txt文件发送多行数据的TCP客户端,一个接受连接并逐行接收的TCP服务器。

它可以工作,但是当传输结束并且客户端关闭套接字时,服务器会一起接收所有行。我不明白为什么,因为我在每行发送到客户端后使用flush,我一直认为这是为了避免这种情况。

如果我的 test.txt 文件包含数字 1 2 3 ... 10,每一个都在一个新行中,服务器的输出是:“12345678910”,然后在控制台中写入一个新行“null”。

服务器代码:

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

class ServidorTCP {

  private String HOST;
  static final int PUERTO = 20001;

      public ServidorTCP( ) {
        try{
          ServerSocket skServidor = new ServerSocket(PUERTO);
              Socket skCliente = skServidor.accept();
          DataInputStream inFromClient = new DataInputStream(new BufferedInputStream(skCliente.getInputStream()));

          while(true){
              String lineaLeida = inFromClient.readUTF();
              if(lineaLeida.equals("END")) break;
              System.out.println(lineaLeida);
          }
              inFromClient.close();
              skCliente.close();
          skServidor.close();
          System.out.println( "Transmission ended" );
        } catch( Exception e ) {
          System.out.println( e.getMessage() );
        }
      }


      public static void main( String[] arg ) {
        new ServidorTCP();
      }

    }

客户代码:

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

class ClienteTCP {

  static final String HOST = "192.168.1.201";
  static final int PUERTO = 20001;

  public ClienteTCP( ) {
    try{
      Socket skCliente = new Socket(HOST, PUERTO);
      if(skCliente.isConnected()) System.out.println("Connected!");
      DataOutputStream outToServer = new DataOutputStream(skCliente.getOutputStream());

      File testFile = new File("test.txt");
      BufferedReader input = new BufferedReader(new FileReader(testFile));
      String line;
      while((line=input.readLine())!=null) {
        if(!line.endsWith("\n")) line = line + "\n";
        System.out.println("Sending: " + line);
        outToServer.writeBytes(line);
        outToServer.flush();
        Thread.currentThread().sleep(1000);
      }
      outToServer.writeBytes("END");
      input.close();
      outToServer.close();
      skCliente.close();
    } catch( Exception e ) {
      System.out.println( e.getMessage() );
    }
  }


  public static void main( String[] arg ) {
    new ClienteTCP();
  }

}

问题出在哪里?

编辑:我已按照建议编辑了代码。现在没有收到任何东西

【问题讨论】:

    标签: java sockets tcp flush


    【解决方案1】:

    问题不在于阅读或写作(或至少不是明确的)。问题是你的字符串。 input.readLine() 删除 end of line 这意味着您发送的字符串只是数字。在服务器端,您会收到很多字符串,但 inFromClient.readLine() 会一直等待,直到它得到一个 end of line,直到流关闭并发送一个 end of file 才到达。

    只需在您发送的每个字符串中添加一个end of line 即可。

    【讨论】:

    • 我尝试在发送的每一行末尾添加一个 \n,但在接收端仍然发生同样的情况
    【解决方案2】:

    事实上,您的代码根本不起作用,更不用说在套接字关闭之前或之后。您正在使用writeUTF() 写作并使用readLine(). 阅读这不起作用。您需要:

    1. DataOutputStream.writeUTF()写,用DataInputStream.readUTF()

    2. 使用println()(由多个 I/O 类提供)、write()print()(由多个 I/O 类提供)写入,后跟 BufferedWriter.newline(),或

    3. ObjectOutputStream.writeObject()写,用ObjectInputStream.readObject()读。

    等等。使用一个 API 编写和使用非对称 API 读取是行不通的。

    【讨论】:

    • 原因是我尝试使用'DataInputStream in = new DataInputStream(socket.getInputStream())',并且在编译时说它已被弃用:|那我应该用什么?
    • 我现在使用“DataInputStream inFromClient = new DataInputStream(new BufferedInputStream(skCliente.getInputStream()))”,然后是“String lineaLeida = inFromClient.readUTF()”。问题依然存在
    • @RomanRdgz 难以置信,但另一个问题是,当您应该关闭 outToServer 时,您正在关闭套接字。
    • 我不太确定,但 BufferedInputStream 可能是问题所在?这可能会延迟传入的数据,以便一次读取所有数据。
    • @denahiro No. BufferedInputStream 将在调用其read() 方法时读取并缓冲任何可读取的数据,阻塞直到至少有一个字节可用。这是所有InputStreams的总合同。
    猜你喜欢
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 2015-12-26
    相关资源
    最近更新 更多