SocketException occurs when reading from the TIG server

I wrote a TIG client which could send message of text properties to TIG server(windows) and parse the message sent by TIG server then write to a image file.

It works well when the TIG client and TIG server are distributed on different machines.
But if they are on the same machine, it becomes very flaky.
Sometimes it works, sometimes exception is thrown out.

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at com.google.tigClient.TigClient.readPixel(TigClient.java:154)
at com.google.tigClient.TigClient.generateImage(TigClient.java:136)
at com.google.tigClient.TigClient.sendSynMsg(TigClient.java:88)

I don't know why there was connect reset.
I used a tool to see whether the data had been sent to client, it seems that the data had been sent to client.
But when the client processing the data, the server reset the connection, which made the SocketException came out.

A possible solution may be reading the whole message sent by TIG server at one time and writing it to a big buffer, then do the data processing.

Does anyone know how to write a stable TIG client?

Thanks~

Here is the related code:
/**
   * Sends the text style to the TIG server, gets the image data and generates the
   * image in the given imagePath.
   *
   * @param textStyle the text style map, like: {"TEXT" : "Google", "TextFont" : "Helvetica" ,
   *  "TextColor" : "(255,0,0)" , "textsize" : "12"}
   * @param imagePath the path of the image that will be generated.
   * @throws SocketException
   * @throws IOException
   * @throws SAXException
   * @throws ParserConfigurationException
   */
 public void sendSynMsg(Map<String> textStyle, String imagePath)
      throws SocketException,  IOException, SAXException, ParserConfigurationException  {
    try {
      socket = new Socket();
      socket.setTcpNoDelay(true);
      socket.connect(server_endpoint);

      out = socket.getOutputStream();
      in = socket.getInputStream();

      PlistBuilder plistBuilder = new PlistBuilder(textStyle);
      // A request is a string in XML plist format containing the text and
      // associated properties such as font, size, and colors. The TIG server returns
      // the metadata + image data.
      byte[] datas = plistBuilder.build();
      logger.info("plist is:" + new String(datas));
      out.write(datas);
      byte[] endMark = new byte[1];
      endMark[0] = 0x04;
      out.write(endMark);
      out.flush();

      int headerSize = readHeaderSize(in);
      String header = readHeader(in, headerSize);
      logger.info("header is: " + header);

      generateImage(in, header, imagePath);
    } finally {
      if (out != null) {
        try {
          out.close();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
      if (in != null) {
        try {
          in.close();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
      if (socket != null) {
        try {
          socket.close();
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
  }




  /**
   * Parses the header to get the width and length of the image, reads image
   * data (pixel values) from the InputStream then generates the image at the
   * given image path.
   */
  private void generateImage(InputStream in, String header, String imagePath)
      throws ParserConfigurationException, SAXException, IOException {
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = builderFactory.newDocumentBuilder();
    InputStream is = new ByteArrayInputStream(header.getBytes());
    Document doc = docBuilder.parse(is);
    Element plist = doc.getDocumentElement();

    Node dict = PlistParser.getChild(plist, "dict");

    int width = PlistParser.integerValueForNamedKey(dict, "WIDTH");
    int height = PlistParser.integerValueForNamedKey(dict, "HEIGHT");

    BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
    int rgb = 0;
    for (int r = 0; r < height; r++) {
      for (int c = 0; c < width; c++) {
        rgb = readPixel(in);
        img.setRGB(c, r, rgb);
      }
    }

    try {
      ImageIO.write(img, "png", new File(imagePath));
      return;
    } catch (IOException e) {
      e.printStackTrace();
    }
    return;
  }

  private int readPixel(InputStream in) throws IOException {
    int argb = 0;
    int temp = 0;
    for (int i = 0; i < 3; ++i) {
      temp = in.read();
      if (temp == -1) {
        throw new IOException("Failed to read one pixel.");
      }
      argb = argb << 8;
      argb += temp;
    }
    temp = in.read();
    argb += temp << 24;
    return argb;
  }
[/code]
Sign In or Register to comment.