To read and write bytes via Socket

575 views
Skip to first unread message

Yoshinori Kohyama

unread,
Aug 28, 2013, 10:13:31 PM8/28/13
to clo...@googlegroups.com
Hello all.

Please help me to read and write bytes via Socket.

For example, assumed that I want to send 5 bytes [0x00, 0x01, 0x7f, 0x80, 0xff] to a TCP server.

I did:
(require '[clojure.java.io :refer :all])
(with-open [s (java.net.Socket. "ip.of.test.server" port_of_test_server)]
  (let [^java.io.BufferedWriter wtr (writer s)
        ^chars obuf (char-array (map char [0 1 127 128 255]))]
    (.write wtr obuf 0 5)
    (.flush wtr))))

Then, my test server received bytes: [0x00, 0x01, 0x7f, 0xc2, 0x80, 0xc3, 0xbf].

* I think I should use a char array so that read() requires 'char[]'.
* What is the valid char value to send a byte 0x80?
* How can I make the char value from 0x80 int?
* How are things about read.
* Does character encoding environment affect? (I use -Dfile.encoding=UTF-8)

Thank you in advance.

Yoshinori Kohyama

Armando Blancas

unread,
Aug 28, 2013, 11:39:11 PM8/28/13
to clo...@googlegroups.com
With UTF-8 characters are encoded in a variable number of bytes according to various ranges, as you can see here in section "Description":
 
Since you're sending your bytes as chars but read back as bytes, your last two bytes create chars that later produce two bytes each, and thus you see seven bytes at the other end. You may want to get an output stream from the socket and write single bytes directly.

Yoshinori Kohyama

unread,
Aug 29, 2013, 12:41:42 AM8/29/13
to clo...@googlegroups.com
Armando, thank you for your reply.

Writing single value with
  void write(int c)
sends same 2 bytes for values larger than 127 as using
  void write(char[] cbuf, int off, int len)

Code:
  (require '[clojure.java.io :refer :all])
  (with-open [s (java.net.Socket. "ip.of.test.serverport_of_test_server)]
    (let [^java.io.BufferedWriter wtr (writer s)]
      (doseq [i [0 1 127 128 255]]
        (.write wtr i))
      (.flush wtr)))
sends same bytes as code in my previous post.

I can't find other appropriate methods of BuffererdReader, Reader and OutputStreamReader
than
  void write(int c)
  void write(char[] cbuf)
  void write(char[] cbuf, int off, int len)
.

Does anyone have any information?
Thanks in advance.

Yoshinori Kohyama

Yoshinori Kohyama

unread,
Aug 29, 2013, 1:10:22 AM8/29/13
to clo...@googlegroups.com
Resolved.

I overlooked that OutputStream has
  void write(byte[] b, int off, int len)
.

With write(byte[] ...) of OutputStream instead of write(char[] ...) of BufferedWritersends I can send the bytes that I want to send.

Code:
  (require '[clojure.java.io :refer :all])
  (with-open [s (java.net.Socket. "ip.of.test.server" port_of_test_server)]
    (let [^java.io.OutputStream os (.getOutputStream s)
          ^bytes obuf (byte-array (map #(byte (if (< % 128) % (- % 256)))
                                       [0 1 127 128 255]))]
      (.write os obuf 0 5)
      (.flush os)))

sent [0x00, 0x01, 0x7f, 0x80, 0xff] to my test server.

Thank you, Armando and all.

Regards,
Yoshinori Kohyama


Reply all
Reply to author
Forward
0 new messages