examples/sucribe/basic-1.c
分析:
1. 定义结构体 struct mosquitto
struct mosquitto {
#if defined(WITH_BROKER) && defined(WITH_EPOLL)
/* This *must* be the first element in the struct. */
int ident;
#endif
...
mosq_sock_t sock;
char *address; // 指针变量 属性
char *id;
char *username;
...
void (*on_connect)(struct mosquitto *, void *userdata, int rc); //回调函数
...
};
结构体包含需要用到的变量属性和回调函数。对于不确定的长度的数据 如name定位为char *
2. 应用
int main(int argc, char *argv[])
{
struct mosquitto *mosq; //定义指针变量
int rc;
mosquitto_lib_init();
mosq = mosquitto_new(NULL, true, NULL); //实际为 mosq 分配一段内存
if(mosq == NULL){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
rc = mosquitto_connect(mosq, "test.mosquitto.org", 1883, 60);
if(rc != MOSQ_ERR_SUCCESS){
mosquitto_destroy(mosq); // 释放内存,重置部分指针变量和回调。
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
return 1;
}
mosquitto_loop_forever(mosq, -1, 1);
mosquitto_lib_cleanup();
return 0;
}
特别说明
struct mosquitto *mosquitto_new(const char *id, bool clean_start, void *userdata)
{
struct mosquitto *mosq = NULL;
int rc;
mosq = (struct mosquitto *)mosquitto__calloc(1, sizeof(struct mosquitto)); //分配内存
if(mosq){
mosq->sock = INVALID_SOCKET;
mosq->sockpairR = INVALID_SOCKET;
mosq->sockpairW = INVALID_SOCKET;
rc = mosquitto_reinitialise(mosq, id, clean_start, userdata); //这个函数分析如下
if(rc){
mosquitto_destroy(mosq);
}
return mosq;
}
// 初始化前如果是重连,不是第一次那么要先释放原来的内存。
int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_start, void *userdata)
{
if(!mosq) return MOSQ_ERR_INVAL;
if(clean_start == false && id == NULL){
return MOSQ_ERR_INVAL;
}
mosquitto__destroy(mosq);
memset(mosq, 0, sizeof(struct mosquitto));
if(userdata){
mosq->userdata = userdata;
}else{
mosq->userdata = mosq;
}
mosq->protocol = mosq_p_mqtt311;
mosq->sock = INVALID_SOCKET;
mosq->keepalive = 60;
mosq->clean_start = clean_start;
if(id){
if(STREMPTY(id)){
return MOSQ_ERR_INVAL;
}
if(mosquitto_validate_utf8(id, (int)strlen(id))){
return MOSQ_ERR_MALFORMED_UTF8;
}
mosq->id = mosquitto__strdup(id);
}
mosq->in_packet.payload = NULL;
packet__cleanup(&mosq->in_packet);
mosq->out_packet = NULL;
mosq->out_packet_count = 0;
mosq->current_out_packet = NULL;
mosq->last_msg_in = mosquitto_time();
mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
mosq->ping_t = 0;
mosq->last_mid = 0;
mosq->state = mosq_cs_new;
mosq->max_qos = 2;
mosq->msgs_in.inflight_maximum = 20;
mosq->msgs_out.inflight_maximum = 20;
mosq->msgs_in.inflight_quota = 20;
mosq->msgs_out.inflight_quota = 20;
mosq->will = NULL;
mosq->on_connect = NULL;
mosq->on_publish = NULL;
mosq->on_message = NULL;
mosq->on_subscribe = NULL;
mosq->on_unsubscribe = NULL;
mosq->host = NULL;
mosq->port = 1883;
mosq->in_callback = false;
mosq->reconnect_delay = 1;
mosq->reconnect_delay_max = 1;
mosq->reconnect_exponential_backoff = false;
mosq->threaded = mosq_ts_none;
#ifdef WITH_TLS
mosq->ssl = NULL;
mosq->ssl_ctx = NULL;
mosq->ssl_ctx_defaults = true;
mosq->tls_cert_reqs = SSL_VERIFY_PEER;
mosq->tls_insecure = false;
mosq->want_write = false;
mosq->tls_ocsp_required = false;
#endif
#ifdef WITH_THREADING
pthread_mutex_init(&mosq->callback_mutex, NULL);
pthread_mutex_init(&mosq->log_callback_mutex, NULL);
pthread_mutex_init(&mosq->state_mutex, NULL);
pthread_mutex_init(&mosq->out_packet_mutex, NULL);
pthread_mutex_init(&mosq->current_out_packet_mutex, NULL);
pthread_mutex_init(&mosq->msgtime_mutex, NULL);
pthread_mutex_init(&mosq->msgs_in.mutex, NULL);
pthread_mutex_init(&mosq->msgs_out.mutex, NULL);
pthread_mutex_init(&mosq->mid_mutex, NULL);
mosq->thread_id = pthread_self();
#endif
/* This must be after pthread_mutex_init(), otherwise the log mutex may be
* used before being initialised. */
if(net__socketpair(&mosq->sockpairR, &mosq->sockpairW)){
log__printf(mosq, MOSQ_LOG_WARNING,
"Warning: Unable to open socket pair, outgoing publish commands may be delayed.");
}
return MOSQ_ERR_SUCCESS;
}