简体   繁体   English

如何使用Java正确地从套接字流式传输数据

[英]How to properly stream data from a socket with Java

I am attempting stream data over a socket with Java in an attempt to write a Kafka producer. 我正在尝试使用Java在套接字上传输数据,以尝试编写Kafka生成器。 I've written a class to pull the data in but I'm not getting the results I'd expect. 我写了一个类来提取数据,但我没有得到我期望的结果。 I've got it set up so the data is being streamed from a Linux box. 我已经设置好了,所以数据是从Linux机器上流式传输的。 The source of the data is a csv file that I'm using the nc utility to stream. 数据源是一个csv文件,我正在使用nc实用程序进行流式处理。 The class is running on a Windows 10 machine from Eclipse. 该类在Eclipse的Windows 10计算机上运行。 When I run the class I see two weird things. 当我上课时,我看到了两件奇怪的事情。

  1. The column headers don't get transmitted. 列标题不会传输。
  2. I can only run the class once. 我只能上课一次。 If I want to run it again, I have to stop nc and restart it. 如果我想再次运行它,我必须停止nc并重新启动它。

Below is my code. 以下是我的代码。 Am I missing anything? 我错过了什么吗? At this point I'm just trying to connect to the socket and pull the data over. 此时我只是尝试连接到套接字并将数据拉过来。

I run nc with the following command: $ nc -kl 9999 < uber_data.csv 我使用以下命令运行nc:$ nc -kl 9999 <uber_data.csv

Below is my class 以下是我的课

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

public class Client 
{
static String userInput;

public static void main(String [] args)
{

    try
    {
        InetAddress serverAddress = InetAddress.getByName("servername");
        Socket socket = new Socket(serverAddress, 9999);
        BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        while ((userInput = input.readLine()) != null) {
            System.out.println(input.readLine());
        }

        input.close();
        socket.close();

    }
    catch(UnknownHostException e1)
    {
        System.out.println("Unknown host exception " + e1.toString());
    }
    catch(IOException e2)
    {
        System.out.println("IOException " + e2.toString());
    }
    catch(IllegalArgumentException e3)
    {
        System.out.println("Illegal Argument Exception " + e3.toString());
    }
    catch(Exception e4)
    {
        System.out.println("Other exceptions " + e4.toString());
    }
}
}

First, each call readLine() tries to read line from input stream. 首先,每次调用readLine()尝试从输入流中读取行。 In userInput = input.readLine() you read header, but println(input.readLine()) read body and print in console. userInput = input.readLine()您读取标题,但println(input.readLine())读取正文并在控制台中打印。

while ((userInput = input.readLine()) != null) { 
     System.out.println(userInput); //instead input.readLine()
}

Second, I didn't use nc, but I think problem will solve if you will close socket (and reader) in finally statement. 其次,我没有使用nc,但我认为如果你将在finally语句中关闭socket(和reader),问题就会解决。

I hope it would be helpful. 我希望它会有所帮助。

For the first question: you were trying to print userInput string. 对于第一个问题:您试图打印userInput字符串。 But it's printing the result of another readline() call. 但它正在打印另一个readline()调用的结果。

For the second: after the file has been transferred, you have to stop and restart nc ; 对于第二个:文件传输完毕后,你必须停止并重新启动nc ; no matter what you do from your side. 无论你做什么在你身边。 It's from nc side. 它来自nc方面。

See the nc documentation . 请参阅nc文档

You're throwing away every odd-numbered line. 你扔掉了每一个奇数线。 It should be: 它应该是:

while ((userInput = input.readLine()) != null) {
    System.out.println(userInput);
}

Secondly, you aren't closing the socket. 其次,你没有关闭套接字。 Use a try-with-resources: 使用try-with-resources:

try
{
    InetAddress serverAddress = InetAddress.getByName("servername");
    try (
        Socket socket = new Socket(serverAddress, 9999);
        BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    ) {
        while ((userInput = input.readLine()) != null) {
            System.out.println(input.readLine());
        }
    }
}
catch (...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM