I came across this snippet in a 6-month old system - apparently some rookie didn't know that a socket can be used to send data in both directions. Interestingly, the person correctly handled partial buffers arriving...
import java.net.Socket;
import java.io.IOException;
import java.text.DecimalFormat;// WTF # 1 - do we really need to wrap sockets to encapsulate bidirectional communications?
public class Pipe {
private Socket inbound; // WTF # 2 - actually using two sockets to implement round trip communications
private Socket outbound; // instead of using input AND output channels// WTF # 3 - technically, these args should be 'final', minor wtf public Pipe(String remoteIP, int remotePort) { // WTF # 4 - which connection failed: outbound or inbound? try { outbound = openSocket(remoteIP, remotePort); inbound = openSocket(remoteIP, remotePort); } catch (Exception e) { // WTF # 5 - what was the actual error, other than something went wrong? System.err.println("Unable to establish round trip communications"); } } // WTF # 6 - why create a proc for one line of code - arguably minor wtf - // could be for encapsulation (which would be a valid use), but // in this case I don't think so; also args should be final (minor gripe) private Socket openSocket(String remoteIP, int remotePort) throws IOException { return new Socket(remoteIP, remotePort); } // WTF # 7 - padding involves duplicating buffer storage instead of sending just a 'length' buf first (see below) public void sendOutboundMessage(byte data[]) throws IOException { byte tmp[] = padBufferWithMessageLength(data); outbound.getOutputStream().write(tmp); outbound.getOutputStream().flush(); } // Actually, this is not too bad - it deals with partial buffer reads // WTF # 8 - magic constants (bufLen field size = 6) public byte [] getInboundMessage() throws IOException { byte msgLen[] = new byte[6]; for (int i=0; i<6; i++) { msgLen[i] = (byte)inbound.getInputStream().read(); } int numBytesToRead = Integer.parseInt(new String(msgLen)); int offset = 0; byte data[] = new byte[numBytesToRead]; while (numBytesToRead > 0) { int nRead = inbound.getInputStream().read(data,offset,numBytesToRead); numBytesToRead -= nRead; offset += nRead; } return data; } // WTF # 9 - why duplicate the entire buffer in order to prefix a buf-length // (why not just send one short buffer with buf length, then the main // data buffer afterward, without duplicating storage?) private byte [] padBufferWithMessageLength(byte b[]) { byte tmp[] = new byte[b.length + 6]; // WTF # 10 - why not use a 4 byte int up front to send the message length - gives 2 billion byte messages // - instead of a 6 byte String, with associated conversions DecimalFormat df = new DecimalFormat("000000"); String lenStr = df.format(b.length); System.arraycopy(lenStr.getBytes(),0,tmp,0,6); System.arraycopy(b,0,tmp,6,b.length); return tmp; }
}