#include <gio/gioerror.h>
#include <gio/gsocket.h>
#include <gio/gnetworkaddress.h>
+#include <gio/gnetworkservice.h>
#include <gio/gsocketaddress.h>
#include "glibintl.h"
* it will be a #GTcpConnection.
*
* Since: 2.22
- **/
+ */
G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
* Free the returned object with g_object_unref().
*
* Since: 2.22
- **/
+ */
GSocketClient *
g_socket_client_new (void)
{
* Returns: a #GSocketFamily
*
* Since: 2.22
- **/
+ */
GSocketFamily
g_socket_client_get_family (GSocketClient *client)
{
* be an ipv6 mapped to ipv4 address.
*
* Since: 2.22
- **/
+ */
void
g_socket_client_set_family (GSocketClient *client,
- GSocketFamily family)
+ GSocketFamily family)
{
if (client->priv->family == family)
return;
* Returns: a #GSocketFamily
*
* Since: 2.22
- **/
+ */
GSocketType
g_socket_client_get_socket_type (GSocketClient *client)
{
* as GSocketClient is used for connection oriented services.
*
* Since: 2.22
- **/
+ */
void
g_socket_client_set_socket_type (GSocketClient *client,
- GSocketType type)
+ GSocketType type)
{
if (client->priv->type == type)
return;
/**
* g_socket_client_get_protocol:
- * @client: a #GSocketClient.
+ * @client: a #GSocketClient
*
* Gets the protocol name type of the socket client.
*
* Returns: a #GSocketProtocol
*
* Since: 2.22
- **/
+ */
GSocketProtocol
g_socket_client_get_protocol (GSocketClient *client)
{
* protocol for the socket family and type.
*
* Since: 2.22
- **/
+ */
void
-g_socket_client_set_protocol (GSocketClient *client,
- GSocketProtocol protocol)
+g_socket_client_set_protocol (GSocketClient *client,
+ GSocketProtocol protocol)
{
if (client->priv->protocol == protocol)
return;
* Returns: a #GSocketAddres or %NULL. don't free
*
* Since: 2.22
- **/
+ */
GSocketAddress *
g_socket_client_get_local_address (GSocketClient *client)
{
* a specific interface.
*
* Since: 2.22
- **/
+ */
void
-g_socket_client_set_local_address (GSocketClient *client,
- GSocketAddress *address)
+g_socket_client_set_local_address (GSocketClient *client,
+ GSocketAddress *address)
{
if (address)
g_object_ref (address);
P_("The sockets address family to use for socket construction"),
G_TYPE_SOCKET_FAMILY,
G_SOCKET_FAMILY_INVALID,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_TYPE,
g_param_spec_enum ("type",
P_("The sockets type to use for socket construction"),
G_TYPE_SOCKET_TYPE,
G_SOCKET_TYPE_STREAM,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_PROTOCOL,
g_param_spec_enum ("protocol",
P_("The protocol to use for socket construction, or 0 for default"),
G_TYPE_SOCKET_PROTOCOL,
G_SOCKET_PROTOCOL_DEFAULT,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
g_param_spec_object ("local-address",
P_("Local address"),
P_("The local address constructed sockets will be bound to"),
G_TYPE_SOCKET_ADDRESS,
- G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
}
/**
* Returns: a #GSocketConnection on success, %NULL on error.
*
* Since: 2.22
- **/
+ */
GSocketConnection *
g_socket_client_connect (GSocketClient *client,
GSocketConnectable *connectable,
}
else if (last_error)
{
- g_propagate_error (error, tmp_error);
+ g_propagate_error (error, last_error);
}
else
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error on connect"));
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unknown error on connect"));
break;
}
socket = create_socket (client, address, &last_error);
if (socket != NULL)
{
- if (g_socket_connect (socket, address, &last_error))
+ if (g_socket_connect (socket, address, cancellable, &last_error))
connection = g_socket_connection_factory_create_connection (socket);
g_object_unref (socket);
* In general, @host_and_port is expected to be provided by the user (allowing
* them to give the hostname, and a port overide if necessary) and
* @default_port is expected to be provided by the application.
-
+ *
* In the case that an IP address is given, a single connection
* attempt is made. In the case that a name is given, multiple
* connection attempts may be made, in turn and according to the
Returns: a #GSocketConnection on success, %NULL on error.
*
* Since: 2.22
- **/
+ */
GSocketConnection *
-g_socket_client_connect_to_host (GSocketClient *client,
- const char *host_and_port,
- int default_port,
- GCancellable *cancellable,
- GError **error)
+g_socket_client_connect_to_host (GSocketClient *client,
+ const gchar *host_and_port,
+ guint16 default_port,
+ GCancellable *cancellable,
+ GError **error)
{
GSocketConnectable *connectable;
GSocketConnection *connection;
return connection;
}
+/**
+ * g_socket_client_connect_to_service:
+ * @client: a #GSocketConnection
+ * @domain: a domain name
+ * @service: the name of the service to connect to
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a pointer to a #GError, or %NULL
+ * @returns: a #GSocketConnection if successful, or %NULL on error
+ *
+ * Attempts to create a TCP connection to a service.
+ *
+ * This call looks up the SRV record for @service at @domain for the
+ * "tcp" protocol. It then attempts to connect, in turn, to each of
+ * the hosts providing the service until either a connection succeeds
+ * or there are no hosts remaining.
+ *
+ * Upon a successful connection, a new #GSocketConnection is constructed
+ * and returned. The caller owns this new object and must drop their
+ * reference to it when finished with it.
+ *
+ * In the event of any failure (DNS error, service not found, no hosts
+ * connectable) %NULL is returned and @error (if non-%NULL) is set
+ * accordingly.
+ */
+GSocketConnection *
+g_socket_client_connect_to_service (GSocketClient *client,
+ const gchar *domain,
+ const gchar *service,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GSocketConnectable *connectable;
+ GSocketConnection *connection;
+
+ connectable = g_network_service_new (service, "tcp", domain);
+ connection = g_socket_client_connect (client, connectable,
+ cancellable, error);
+ g_object_unref (connectable);
+
+ return connection;
+}
+
typedef struct
{
GSimpleAsyncResult *result;
g_socket_set_blocking (data->current_socket, TRUE);
connection = g_socket_connection_factory_create_connection (data->current_socket);
+ g_object_unref (data->current_socket);
g_simple_async_result_set_op_res_gpointer (data->result,
connection,
g_object_unref);
g_simple_async_result_complete (data->result);
g_object_unref (data->result);
+ g_object_unref (data->enumerator);
+ g_slice_free (GSocketClientAsyncConnectData, data);
}
if (tmp_error)
set_last_error (data, tmp_error);
else if (data->last_error == NULL)
- g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Unknown error on connect"));
+ g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ _("Unknown error on connect"));
g_socket_client_async_connect_complete (data);
return;
if (socket != NULL)
{
g_socket_set_blocking (socket, FALSE);
- if (g_socket_connect (socket, address, &tmp_error))
+ if (g_socket_connect (socket, address, data->cancellable, &tmp_error))
{
data->current_socket = socket;
g_socket_client_async_connect_complete (data);
g_source_set_callback (source,
(GSourceFunc) g_socket_client_socket_callback,
data, NULL);
- g_source_attach (source, NULL);
+ g_source_attach (source, g_main_context_get_thread_default ());
g_source_unref (source);
g_object_unref (address);
* the result of the operation.
*
* Since: 2.22
- **/
+ */
void
g_socket_client_connect_async (GSocketClient *client,
GSocketConnectable *connectable,
* the result of the operation.
*
* Since: 2.22
- **/
+ */
void
g_socket_client_connect_to_host_async (GSocketClient *client,
- const char *host_and_port,
- int default_port,
+ const gchar *host_and_port,
+ guint16 default_port,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
}
/**
+ * g_socket_client_connect_to_service_async:
+ * @client: a #GSocketClient
+ * @domain: a domain name
+ * @service: the name of the service to connect to
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: a #GAsyncReadyCallback
+ * @user_data: user data for the callback
+ *
+ * This is the asynchronous version of
+ * g_socket_client_connect_to_service().
+ *
+ * Since: 2.22
+ */
+void
+g_socket_client_connect_to_service_async (GSocketClient *client,
+ const gchar *domain,
+ const gchar *service,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSocketConnectable *connectable;
+
+ connectable = g_network_service_new (service, "tcp", domain);
+ g_socket_client_connect_async (client,
+ connectable, cancellable,
+ callback, user_data);
+ g_object_unref (connectable);
+}
+
+/**
* g_socket_client_connect_finish:
* @client: a #GSocketClient.
* @result: a #GAsyncResult.
* Returns: a #GSocketConnection on success, %NULL on error.
*
* Since: 2.22
- **/
+ */
GSocketConnection *
g_socket_client_connect_finish (GSocketClient *client,
GAsyncResult *result,
* Returns: a #GSocketConnection on success, %NULL on error.
*
* Since: 2.22
- **/
+ */
+GSocketConnection *
+g_socket_client_connect_to_host_finish (GSocketClient *client,
+ GAsyncResult *result,
+ GError **error)
+{
+ return g_socket_client_connect_finish (client, result, error);
+}
+
+/**
+ * g_socket_client_connect_to_service_finish:
+ * @client: a #GSocketClient.
+ * @result: a #GAsyncResult.
+ * @error: a #GError location to store the error occuring, or %NULL to
+ * ignore.
+ *
+ * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
+ *
+ * Returns: a #GSocketConnection on success, %NULL on error.
+ *
+ * Since: 2.22
+ */
GSocketConnection *
-g_socket_client_connect_to_host_finish (GSocketClient *client,
- GAsyncResult *result,
- GError **error)
+g_socket_client_connect_to_service_finish (GSocketClient *client,
+ GAsyncResult *result,
+ GError **error)
{
return g_socket_client_connect_finish (client, result, error);
}