在GLib下的libsoup库为HTTP网路通讯提供了支持。网路通讯一般包含两方面的内容,即HTTP信息的发送和接收。
作为客户端,我们可以使用soup_message_new()
或者soup_message_new_from_uri()
函数来获取信息。
SoupMessage * soup_message_new (const char *method, const char *uri_string);
对于服务端,SoupServer 会自动的为传进来的request请求建立SoupMessage .
我们来看一下SoupMessage的结构体,包括:请求类型,返回状态,服务器返回值,request信息,response信息
typedef struct { const char *method; guint status_code; char *reason_phrase; SoupMessageBody *request_body; SoupMessageHeaders *request_headers; SoupMessageBody *response_body; SoupMessageHeaders *response_headers; } SoupMessage;
服务端建立服务:
SoupSession *session; SoupServer *server; session = soup_session_async_new (); server = soup_server_new (NULL); soup_server_add_handler (server, NULL, server_callback, NULL, NULL); soup_server_run_async (server); char *url = g_strdup_printf ("http://localhost:%d/", soup_server_get_port (server));
设置服务处理函数:
static void server_callback (SoupServer *server, SoupMessage *msg, const char *path, GHashTable *query, SoupClientContext *client, gpointer user_data) { if (g_str_equal (path, "/ping")) { soup_message_set_status (msg, SOUP_STATUS_OK); } else if (g_str_equal (path, "/echo")) { const char *value; value = g_hash_table_lookup (query, "value"); soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, value, strlen (value)); soup_message_set_status (msg, SOUP_STATUS_OK); } else if (g_str_equal (path, "/reverse")) { char *value; value = g_strdup (g_hash_table_lookup (query, "value")); g_strreverse (value); soup_message_set_response (msg, "text/plain", SOUP_MEMORY_TAKE, value, strlen (value)); soup_message_set_status (msg, SOUP_STATUS_OK); } else if (g_str_equal (path, "/status")) { const char *value; int status; value = g_hash_table_lookup (query, "status"); if (value) { status = atoi (value); soup_message_set_status (msg, status ?: SOUP_STATUS_INTERNAL_SERVER_ERROR); } } else if (g_str_equal (path, "/useragent/none")) { if (soup_message_headers_get (msg->request_headers, "User-Agent") == NULL) { soup_message_set_status (msg, SOUP_STATUS_OK); } else { soup_message_set_status (msg, SOUP_STATUS_EXPECTATION_FAILED); } } else if (g_str_equal (path, "/useragent/testsuite")) { const char *value; value = soup_message_headers_get (msg->request_headers, "User-Agent"); if (g_strcmp0 (value, "TestSuite-1.0") == 0) { soup_message_set_status (msg, SOUP_STATUS_OK); } else { soup_message_set_status (msg, SOUP_STATUS_EXPECTATION_FAILED); } } }
客户端发送请求:
url = g_strdup ("%s/%s", url, "echo"); gchar *method = g_strdup ("GET"); SoupMessage *message = soup_message_new (method, url); if (message->status_code >= 200 && message->status_code < 300) { g_message ("message call success, value is %s\n",message->response_body->data); return TRUE; }else{ g_message ("message call failed\n"); return FALSE; }