Esempio n. 1
0
/******************************************************************************
 **函数名称: rtrd_rsvr_sck_creat
 **功    能: 创建套接字对象
 **输入参数:
 **     rsvr: 接收服务
 **     req: 添加套接字请求
 **输出参数: NONE
 **返    回: 套接字对象
 **实现描述: 创建套接字对象, 并依次初始化其成员变量
 **注意事项: 套接字关闭时, 记得释放空间, 防止内存泄露!
 **作    者: # Qifeng.zou # 2015.06.11 #
 ******************************************************************************/
static rtrd_sck_t *rtrd_rsvr_sck_creat(rtrd_rsvr_t *rsvr, rtmq_cmd_add_sck_t *req)
{
    void *addr;
    list_opt_t opt;
    rtrd_sck_t *sck;

    /* > 分配连接空间 */
    sck = calloc(1, sizeof(rtrd_sck_t));
    if (NULL == sck) {
        log_error(rsvr->log, "Alloc memory failed!");
        CLOSE(req->sckid);
        return NULL;
    }

    memset(sck, 0, sizeof(rtrd_sck_t));

    sck->fd = req->sckid;
    sck->nodeid = -1;
    sck->sid = req->sid;
    sck->ctm = time(NULL);
    sck->rdtm = sck->ctm;
    sck->wrtm = sck->ctm;
    snprintf(sck->ipaddr, sizeof(sck->ipaddr), "%s", req->ipaddr);

    do {
        /* > 创建发送链表 */
        memset(&opt, 0, sizeof(opt));

        opt.pool = (void *)NULL;
        opt.alloc = (mem_alloc_cb_t)mem_alloc;
        opt.dealloc = (mem_dealloc_cb_t)mem_dealloc;

        sck->mesg_list = list_creat(&opt);
        if (NULL == sck->mesg_list) {
            log_error(rsvr->log, "Create list failed!");
            break;
        }

        /* > 申请接收缓存 */
        addr = (void *)calloc(1, RTMQ_BUFF_SIZE);
        if (NULL == addr) {
            log_error(rsvr->log, "errmsg:[%d] %s!", errno, strerror(errno));
            break;
        }

        rtmq_snap_setup(&sck->recv, addr, RTMQ_BUFF_SIZE);

        return sck;
    } while (0);

    /* > 释放套接字对象 */
    rtrd_rsvr_sck_free(rsvr, sck);
    return NULL;
}
Esempio n. 2
0
/******************************************************************************
 **函数名称: rtrd_rsvr_dist_data
 **功    能: 分发连接队列中的数据
 **输入参数:
 **     ctx: 全局对象
 **     rsvr: 接收服务
 **输出参数: NONE
 **返    回: 0:成功 !0:失败
 **实现描述:
 **注意事项:
 **作    者: # Qifeng.zou # 2015.06.02 #
 ******************************************************************************/
static int rtrd_rsvr_dist_data(rtrd_cntx_t *ctx, rtrd_rsvr_t *rsvr)
{
#define RTRD_POP_MAX_NUM (1024)
    int len, idx, num;
    queue_t *sendq;
    void *addr;
    void *data[RTRD_POP_MAX_NUM];
    rtmq_frwd_t *frwd;
    list_opt_t opt;
    rtrd_sck_t *sck;
    _conn_list_t cl;
    rtmq_header_t *head;

    sendq = ctx->sendq[rsvr->id];

    while (1) {
        /* > 弹出队列数据 */
        num = MIN(queue_used(sendq), RTRD_POP_MAX_NUM);
        if (0 == num) {
            break;
        }

        num = queue_mpop(sendq, data, num);
        if (0 == num) {
            continue;
        }

        log_trace(ctx->log, "Multi-pop num:%d!", num);

        /* > 逐条处理数据 */
        for (idx=0; idx<num; ++idx) {
            frwd = (rtmq_frwd_t *)data[idx];

            /* > 查找发送连接 */
            memset(&opt, 0, sizeof(opt));

            opt.pool = (void *)NULL;
            opt.alloc = (mem_alloc_cb_t)mem_alloc;
            opt.dealloc = (mem_dealloc_cb_t)mem_dealloc;

            cl.nodeid = frwd->dest;
            cl.list = list_creat(&opt);
            if (NULL == cl.list) {
                queue_dealloc(sendq, data[idx]);
                log_error(rsvr->log, "Create list failed!");
                continue;
            }

            list2_trav(rsvr->conn_list, (list2_trav_cb_t)rtrd_rsvr_get_conn_list_by_nodeid, &cl);
            if (0 == cl.list->num) {
                queue_dealloc(sendq, data[idx]);
                list_destroy(cl.list, NULL, mem_dummy_dealloc);
                log_error(rsvr->log, "Didn't find connection by nodeid [%d]!", cl.nodeid);
                continue;
            }

            sck = (rtrd_sck_t *)list_fetch(cl.list, rand()%cl.list->num);
            
            /* > 设置发送数据 */
            len = sizeof(rtmq_header_t) + frwd->length;

            addr = calloc(1, len);
            if (NULL == addr) {
                queue_dealloc(sendq, data[idx]);
                list_destroy(cl.list, NULL, mem_dummy_dealloc);
                log_error(rsvr->log, "Alloc memory from slab failed!");
                continue;
            }

            head = (rtmq_header_t *)addr;

            head->type = frwd->type;
            head->nodeid = frwd->dest;
            head->flag = RTMQ_EXP_MESG;
            head->checksum = RTMQ_CHECK_SUM;
            head->length = frwd->length;

            memcpy(addr+sizeof(rtmq_header_t), data[idx]+sizeof(rtmq_frwd_t), head->length);

            queue_dealloc(sendq, data[idx]);

            /* > 放入发送链表 */
            if (list_rpush(sck->mesg_list, addr)) {
                FREE(addr);
                log_error(rsvr->log, "Push input list failed!");
            }

            list_destroy(cl.list, NULL, mem_dummy_dealloc); /* 无需是否结点数据空间 */
        }
    }

    return RTMQ_OK;
}
Esempio n. 3
0
int main(void)
{
	int sev_fd,cli_fd,cli_addr_len;			//客户端、服务器端描述符,客户端地址长度
	char *ifo;								//错误提示
	struct sockaddr_in cli_addr,sev_addr;	//客户端、服务器地址结构
	fd_set readfds,testfds;					//监控集合
	int cli_count = 0,recv_count,result;	//连接数目、收到字节数目、发生时间数目
	onlinelist *pHead, *pNew, *pTemp, *pTar;		//链表操作
	datapack buf;							//数据包

	//开启服务,添加系统日志
	ifo = "The server is strart";
	add_syslog_sev(ifo);

	//初始化socket
	sev_fd = socket(AF_INET, SOCK_STREAM, 0);
	if (sev_fd < 0){
		ifo = strerror(errno);
		add_errorlog_sev(ifo);
		return EXIT_FAILURE;
	}
	int on = 1;
	if (setsockopt(sev_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){
		ifo = strerror(errno);
		add_errorlog_sev(ifo);
		return EXIT_FAILURE;
	}
	//初始化server端IP;
	sev_addr.sin_family = AF_INET;
	sev_addr.sin_port = htons(2489);
	sev_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	//绑定端口
	if (bind(sev_fd,(struct sockaddr *)&sev_addr,sizeof(sev_addr)) == -1){
		ifo = strerror(errno);
		add_errorlog_sev(ifo);
		return EXIT_FAILURE;
	}
	//监听
	if (listen(sev_fd,40) == -1){
		ifo = strerror(errno);
		add_errorlog_sev(ifo);
		return EXIT_FAILURE;
	}

	//创建一条链表用于存储连接上的用户套接字描述符
	list_creat(pHead,onlinelist);

	FD_ZERO(&readfds);
	FD_SET(sev_fd,&readfds);
	pNew = (onlinelist *)malloc(sizeof(onlinelist));
	pNew->sock = sev_fd;
	add_tial(pHead, pNew, onlinelist);
	cli_count++;

	while(1){
		testfds = readfds;
		result = select(100,&testfds,NULL,NULL,NULL);
		if (result == -1){
			ifo = strerror(errno);
			add_errorlog_sev(ifo);
			return EXIT_FAILURE;
		}
		if (result > 0){
			pTemp = pHead->pNext;
			while(pTemp != NULL){
				if (FD_ISSET(pTemp->sock,&testfds)){
					if (pTemp->sock == sev_fd){
						//接受连接
						cli_addr_len = sizeof(cli_addr);
						cli_fd = accept(sev_fd,(struct sockaddr *)&cli_addr,&cli_addr_len);
						if (cli_fd < 0){
							ifo = strerror(errno);
							add_errorlog_sev(ifo);
							return EXIT_FAILURE;
						}
						FD_SET(cli_fd, &readfds);
						pNew = (onlinelist *)malloc(sizeof(onlinelist));
						pNew->sock = cli_fd;
						strcpy(pNew->ip, inet_ntoa(cli_addr.sin_addr));
						add_tial(pHead, pNew, onlinelist);
						cli_count++;
					}
					else{
						memset(&buf,0,sizeof(buf));
						recv_count = recv(pTemp->sock, &buf, sizeof(buf),0);
						if (recv_count == 0){
							cli_count--;
							close(pTemp->sock);
							FD_CLR(pTemp->sock,&readfds);
							userlogout_sev(pTemp->id, pTemp->ip);
							pTar = pTemp;	pTemp = pTemp->pNext;
							del_node(pHead, pTar, onlinelist);
							if (pTemp == NULL)
								break;
						}
						else{
							analyzedatapack(&buf, pTemp->sock, pTemp->ip, pHead, pTemp);
						}
					}
				}
				pTemp = pTemp->pNext;
			}
		}
	}

	close(sev_fd);

	//关闭服务,添加系统日志
	ifo = "The server is close";
	add_syslog_sev(ifo);

	return EXIT_SUCCESS;
}
Esempio n. 4
0
static void list_test()
{
   list_creat();
   list_print();

   // this is WRONG...

   printf("*****WRONG************\n");

   node* item;
   node** ptr;

   for (ptr = &node::first; (item = *ptr); ptr = &(*ptr)->next)
      {
      printf("item: %p %p %d\n", item, item->next, item->data);

      if (item->data == 2) list_remove(ptr);
      }

   list_print();

   printf("**********************\n");

   // this is WRONG...

   list_destroy();
   list_creat();
   list_print();

   printf("*****WRONG************\n");

   item =  node::first;
   ptr  = &node::first;

   do {
      printf("item: %p %p %d\n", item, item->next, item->data);

      if (item->data == 2) list_remove(ptr);

      ptr = &(*ptr)->next;
      }
   while ((item = *ptr));

   list_print();

   printf("**********************\n");

   // this is WRONG...

   list_destroy();
   list_creat();
   list_print();

   printf("*****WRONG************\n");

   ptr = &node::first;

   while ((item = *ptr))
      {
      printf("item: %p %p %d\n", item, item->next, item->data);

      if (item->data == 3) list_remove(ptr);

      ptr = &(*ptr)->next;
      }

   list_print();

   printf("**********************\n");

   // this is OK...

   list_destroy();
   list_creat();
   list_print();

   printf("*****OK***************\n");

   ptr = &node::first;

   while ((item = *ptr))
      {
      printf("item: %p %p %d\n", item, item->next, item->data);

      if (item->data == 3)
         {
         list_remove(ptr);

         continue;
         }

      ptr = &(*ptr)->next;
      }

   list_print();

   printf("**********************\n");

   // this is OK...

   list_destroy();
   list_creat();
   list_print();

   printf("*****OK***************\n");

   item =  node::first;
   ptr  = &node::first;

   do {
      printf("item: %p %p %d\n", item, item->next, item->data);

      if (item->data == 2)
         {
         list_remove(ptr);

         continue;
         }

      ptr = &(*ptr)->next;
      }
   while ((item = *ptr));

   list_print();

   printf("**********************\n");

   exit(0);
}