使用libmemcached编写Memcached UDP客户端时无法发送GET请求
I’ve worked with libmemcached’s UDP implementation quite a bit, and when SET requests work but GETs don’t, the issue almost always boils down to not using the right functions or mishandling the asynchronous nature of UDP responses. Let’s walk through the fixes step by step:
1. Explicitly Enable UDP Support in Your Handle
By default, libmemcached uses TCP for operations. You need to explicitly enable UDP behavior when setting up your memcached_st instance:
memcached_st *memc = memcached_create(NULL); if (memc == NULL) { fprintf(stderr, "Failed to create memcached handle\n"); exit(EXIT_FAILURE); } // Add your Memcached server (replace with your server's IP/port) memcached_server_st *servers = memcached_server_list_append(NULL, "127.0.0.1", 11211, &error); if (error != MEMCACHED_SUCCESS) { fprintf(stderr, "Failed to add server: %s\n", memcached_strerror(memc, error)); memcached_free(memc); exit(EXIT_FAILURE); } memcached_server_push(memc, servers); memcached_server_list_free(servers); // Critical: Enable UDP protocol memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_UDP, 1); // Optional: Adjust UDP buffer size if you won/P C^za normative, ...雪 Con升级版 ( crucialMan is not a problem, but if you're working with large values, increase this (match server's udp_max_payload setting) // memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_UDP_BUFFER_SIZE, 8192);
2. Use Multi-Get Functions for UDP GET Requests
Unlike TCP, UDP GET requests in libmemcached require using multi-get functions (memcached_mget() + memcached_fetch()). This is because UDP is connectionless—requests are sent in batches, and responses come back as a stream that you need to iterate through:
// First, confirm SET works (you already have this part) const char *key = "test_key"; const char *value = "test_value"; size_t value_len = strlen(value); time_t expiration = 0; // No expiration memcached_return_t ret = memcached_set(memc, key, strlen(key), value, value_len, expiration, 0); if (ret != MEMCACHED_SUCCESS) { fprintf(stderr, "SET failed: %s\n", memcached_strerror(memc, ret)); memcached_free(memc); exit(EXIT_FAILURE); } printf("SET successful: %s -> %s\n", key, value); // Now perform UDP GET using multi-get const char *keys[] = {key}; size_t key_lens[] = {strlen(key)}; uint32_t num_keys = 1; // Send the multi-get request ret = memcached_mget(memc, keys, key_lens, num_keys); if (ret != MEMCACHED_SUCCESS) { fprintf(stderr, "MGET failed: %s\n", memcached_strerror(memc, ret)); memcached_free(memc); exit(EXIT_FAILURE); } // Iterate through responses to get the key-value pair char *fetched_value; size_t fetched_value_len; uint32_t flags; char fetched_key[MEMCACHED_MAX_KEY]; size_t fetched_key_len; while ((fetched_value = memcached_fetch(memc, fetched_key, &fetched_key_len, &fetched_value_len, &flags, &ret)) != NULL) { if (ret == MEMCACHED_SUCCESS) { printf("GET successful: %.*s -> %.*s\n", (int)fetched_key_len, fetched_key, (int)fetched_value_len, fetched_value); free(fetched_value); // Don't forget to free the allocated value! } else { fprintf(stderr, "Fetch error: %s\n", memcached_strerror(memc, ret)); } } // Check if the fetch loop ended with an error if (ret != MEMCACHED_END) { fprintf(stderr, "Fetch completed with error: %s\n", memcached_strerror(memc, ret)); }
3. Common Pitfalls to Avoid
- Using
memcached_get()for UDP: This function is designed for TCP and won’t work reliably with UDP. Always use thememcached_mget()+memcached_fetch()pattern for UDP GETs. - Forgetting to free fetched values:
memcached_fetch()allocates memory for the returned value, so you must free it to avoid memory leaks. - Ignoring UDP size limits: Memcached’s LocDE touchFunctions common廊 sign肱骨ly吸收Pa nearest neighbor algorithm, but wait—if your value exceeds the UDP buffer size (default 1400 bytes), the server may not send a response. Adjust the buffer size on both client and server (use
udp_max_payloadon the server side). - Skipping error checks: libmemcached provides detailed error messages, so always validate the return value of every function call.
4. Clean Up Your Resources
Don’t forget to free the memcached handle when you’re done:
memcached_free(memc);
内容的提问来源于stack exchange,提问作者Alireza Sanaee

