errordomain Error { MESSAGE } //compile with: valac --pkg=gio-2.0 tcpClient.vala public class TcpClient { private InetAddress inetAddress; private int port; private SocketConnection conn; private SocketClient client; public signal void DataReceived(uint8 byte); public signal void Disconnected(); private bool connected = false; public TcpClient () { //stdout.printf("TcpClient: Instantiated.\n"); } public void Connect(string ipAddress, int port) throws IOError { inetAddress = new InetAddress.from_string(ipAddress); this.port = port; client = new SocketClient(); stdout.printf("TcpClient: Trying to connect to "+inetAddress.to_string()+":"+port.to_string()+"...\n"); try { process_request(); } catch (Error e) { stderr.printf("TcpClient.Connect(): Starting reading process failed.\n\t"+e.message+"\n"); } } /** * Reports whether the connection got * terminated either by the client or by the host. */ public void Disconnect() { if(!conn.closed) { try { stdout.printf("TcpClient.Disconnect(): Disconnecting...\n"); conn.socket.close(); conn.close(); this.connected = false;//set state first! Disconnected();//then fire event to anounce the state. conn.dispose(); client.dispose(); conn = null; client = null; } catch (GLib.IOError e) { stderr.printf("TcpClient.Disconnect(): Had trouble closing the connection. Stopped reading anyway.\n\t"+e.message+"n"); } } else { stdout.printf("TcpClient.Disconnect(): Already disconnected.\n"); } } public bool Connected { get { return this.connected; } } public void Write(string message) { if(connected) { //stdout.printf("TcpClient: Trying to write \""+message+"\" into the stream.\n"); try { conn.output_stream.write(message.data, null); } catch (GLib.IOError e) { stderr.printf("TcpClient.Write(): Couldn't write \""+message+"\" into stream.\n\t"+e.message+"\n"); Disconnect(); } //stdout.printf("TcpClient: Done writing \""+message+"\" into the stream.\n"); } else { stdout.printf("tcpClient.Write(): Not connected. Won't send \""+message+"\".\n"); } } public void WriteByte(uint8 byte) { if(connected) { //stdout.printf("tcpClient.WriteByte(): Sending \""+byte.to_string()+"\"...\n"); try { conn.output_stream.write(new uint8[]{byte}); } catch (GLib.IOError e) { stderr.printf("TcpClient.WriteByte(): Couldn't write byte \""+byte.to_string()+"\" into stream.\n\t"+e.message+"\n"); Disconnect(); } } else { stdout.printf("tcpClient.WriteByte(): Not connected. Won't send \""+byte.to_string()+"\".\n"); } } private void process_request () throws Error { InetSocketAddress socketAddress = new InetSocketAddress(inetAddress, (uint16)port); try { conn = client.connect(socketAddress, null); if(!conn.closed) { stdout.printf("TcpClient: Connected.\n"); connected = true; } } catch (GLib.Error e) { stderr.printf("TcpClient.process_request(): Could not establish connection.\n\t"+e.message+"\n"); //Disconnect(); return; } // we set the socket back to blocking here for the convenience // of DataInputStream //conn.socket.set_blocking (true); DataInputStream input = new DataInputStream (conn.input_stream); ThreadFunc run = () => { while(connected) { try { uint8 byte = input.read_byte(null); DataReceived(byte); stdout.printf(((unichar)byte).to_string()); } catch (GLib.IOError e) { stderr.printf("tcpClient.process_request(): Had trouble reading input byte.\n\t"+e.message+"\n"); Disconnect(); return null; } } return null; }; new Thread("readThread", run); } }