How to generate byte arrays for sending data over a network in Java -
i trying connect postgresql server (implementing wire protocol) can't figure out how dynamically generate message frames of byte arrays. example, in following code i'm doing lot of system.arraycopy
calls push generated bytes single byte array , seems there has better way.
import java.io.*; import java.net.socket; import java.nio.bytebuffer; public class connection { public void connect(string hostname, int port) { try { socket dbsocket = new socket(hostname, port); dataoutputstream dout = new dataoutputstream(dbsocket.getoutputstream()); byte[] message = buildstartupmessage("sa"); dout.write(message); datainputstream din = new datainputstream(dbsocket.getinputstream()); byte bytes; while((bytes = din.readbyte()) != 0) { system.out.println(bytes); } } catch(exception e) { system.out.println("got exception"); } } public byte[] buildstartupmessage(string username) { // postgres startup message format: // 32 bit length // 32 bit protocol // string name // null byte // string value // null byte byte nullbyte = 0; byte[] valbytes = username.getbytes(); byte[] namebytes = "user".getbytes(); system.out.println("number of bytes sa is: " + valbytes.length); int length = 4 + 4 + valbytes.length + namebytes.length + 2; byte[] lengthbytes = bytebuffer.allocate(4).putint(length).array(); byte[] protocolbytes = bytebuffer.allocate(4).putint(3).array(); byte[] startupmessage = new byte[length]; int currindex = 0; system.arraycopy(lengthbytes, 0, startupmessage, currindex, lengthbytes.length); currindex += lengthbytes.length; system.arraycopy(protocolbytes, 0, startupmessage, currindex, protocolbytes.length); currindex += protocolbytes.length; system.arraycopy(namebytes, 0, startupmessage, currindex, namebytes.length); currindex += namebytes.length; startupmessage[currindex] = nullbyte; currindex++; system.arraycopy(valbytes, 0, startupmessage, currindex, valbytes.length); currindex += valbytes.length; startupmessage[currindex] = nullbyte; return startupmessage; } public static void main(string[] args) { connection conn = new connection(); conn.connect("localhost", 5432); } }
don't. use primitives of dataoutputstream
write want directly. example:
dos.writeint(length); // total length dos.writeint(3); // protocol dos.writebytes("user"); dos.writebyte(0); // null terminator dos.writebytes(username); // username dos.writebyte(0); // null terminator
... , converse when reading via datainputstream
, according protocol. put buffered streams under data streams save system calls.
but ... real question here 'why'? should using postgressql jdbc driver talk server, rather trying roll entire protocol yourself. it's done you, vendor. don't this.
nb when exception, don't print out got exception.
asinine. print exception.
Comments
Post a Comment