Hi all,
 
I've written a little tcp client class and it works well, except that I can't 
disconnect an existing connection.



private SocketClient client;
private SocketConnection conn;

public void Connect()
{
  client = new SocketClient();
  conn = client.connect(socketAddress, null);
}


public void Disconnect()
{
  stdout.printf("TcpClient.Disconnect(): Disconnecting...\n");//I do arrive 
here.
  conn.socket.close();
  conn.close();
  conn.dispose();
  client.dispose();
  conn = null;
  client = null;

  //no exception/assertion will occour. All the commands will be executed but 
won't affect the connection.
}

None of what I'm trying here does really disconnect my connection. I traced it 
in Wireshark and nothing happens (no RST). Even nulling the instance of my own 
Tcp client doesn't help. Unless I close my whole application, only then the 
connection will be terminated. But I can't force the user to close the 
application just to disconnect and connect again.

I'll be glad about any help. Thanks.

gilzad
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<void*> 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<void*>("readThread", run);
  }
}
_______________________________________________
vala-list mailing list
vala-list@gnome.org
https://mail.gnome.org/mailman/listinfo/vala-list

Reply via email to