在套接字上写一个大字符串时出错?

时间:2011-10-12 14:53:00

标签: java sockets tcp bufferedreader bufferedwriter

大家好朋友,

我正在尝试通过套接字连接发送一个长字符串,但我将它们分成两部分,所以在执行我的进程时出现错误。

在客户端我发送文件

BufferedWriter bufferedOut = null;
BufferedReader in = null;
socket = new Socket("192.168.0.15",4444);
bufferedOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

bufferedOut.write(xmlInString, 0, xmlInString.length());

/**
* wait for response
*/

byte[] buf = new byte[10000];
int actualNumberOfBytesRead = socket.getInputStream().read(buf);
String responseLine = new String(buf, 0, actualNumberOfBytesRead);

在服务器中,

 BufferedReader in = null;
 PrintWriter out = null;
 in = new BufferedReader(new InputStreamReader(client.getInputStream()));
 out = new PrintWriter(client.getOutputStream(), true);

//get the input
 byte[] buf = new byte[10000];
 int actualNumberOfBytesRead = client.getInputStream().read(buf);
 line = new String(buf, 0, actualNumberOfBytesRead);
 //send back
 out.println(result);

我如何才能将我的字符串作为一部分?你能告诉我我在代码上的错误在哪里吗?

谢谢大家

2 个答案:

答案 0 :(得分:1)

您需要一个循环来重复读取输入流,每次将读取的数据连接在一起,直到到达字符串的末尾。

编辑 - 更多细节。如果您正在寻找传输多个此类字符串/文件,请参阅@ arnaud的答案。如果您所有想要发送的是1个大字符串,那么:

  1. 在发件人方面,创建输出流,发送数据(如您所做),然后不要忘记再次关闭流(这也将执行刷新以确保数据被发送通过电线,并通知另一端没有更多的数据来。)

  2. 在收件人站点上,循环读取数据,直到输入流结束(read(buf)返回-1),每次在一个大缓冲区中将数据连接在一起,然后关闭输入流。< / p>

  3. 另外,请阅读我关于将文件作为字节而不是字符串发送的评论。这对于XML文件尤其重要,因为XML文件具有相当特殊的编码检测规则。

答案 1 :(得分:1)

使用TCP套接字时,您正在处理“流”。也就是说,默认情况下,消息之间没有分隔。通过按照您的方式进行操作,您可能会阅读部分信息,或者更糟糕的是,阅读的信息不仅仅是信息。

最常见的方法是分隔您的邮件。您可以使用DataInputStream / DataOutputStream将字符串编码为字节,并使用第一个字节来指示它的长度。这样,它就知道它应该在接收端读取多少字节。

    DataOutputStream out = null;
    DataInputStream in = null;
    Socket socket = new Socket("192.168.0.15",4444);
    out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

    out.writeUTF(xmlInString);
    out.flush(); // to ensure everything is sent and nothing is kept in the buffer.

    // wait for response

    String responseLine = in.readUTF();

然后,相应地调整服务器代码。

当使用带有套接字的Buffered输出时,建议出于性能原因,建议您在编写消息后flush()确保所有内容都是通过网络实际发送的,并且不保留任何内容缓冲区。

您的初始问题可能是因为您的邮件需要多个TCP / IP数据包,而在您的服务器中,您只读取刚刚到达的第一个邮件。