IPMSG飞鸽传书5——网络协议解析手记2

每次IPMSG在收到上线通告报文后,都要查找相同ip的节点是否已经存在,只要和结构 体成员host_ip比较就可以了,这样整个用户列表当中的成员是不会重复的。报文的发送主要依靠下边的函数实现,这里推荐下边的这种写法,特别是对与命 令比较多的情况下,使用下边的好处就在与结构非常的清晰。

 

mode: 命令 msg: 附加信息 struct sockaddr * p:网络信息 fd:网络套接字描述符

int msg_send( const int mode, const char * msg, const struct sockaddr * p, int fd)
{
    int udp_fd= fd;
    int broadcast_en= 1;
    char msg_buf[ SND_BUF_LEN] ;
    char * use= "test" , * group= "sunplusapp" ;
    socklen_t broadcast_len= sizeof ( broadcast_en) ;
    long int msg_id= time ( ( time_t * ) NULL ) ;
    struct sockaddr_in udp_addr;
    struct sockaddr client;
     bzero( msg_buf, SND_BUF_LEN) ;
     bzero( & udp_addr, sizeof ( struct sockaddr_in ) ) ;
     udp_addr. sin_family= AF_INET ;
     udp_addr. sin_port= htons ( IPMSG_UDP_PORT) ;
     inet_pton( AF_INET , BR_IP, & udp_addr. sin_addr. s_addr) ;

//下边的if 与else if :对于上线通告 下线等使用广播地址,其他的则否
    if ( ( p= = NULL ) & & ( mode!=IPMSG_NOOPERATION) & & ( mode!=IPMSG_BR_ENTRY) & & ( mode!=IPMSG_BR_EXIT) )
    {
        printf ( "p is NULL,only mode = IPMSG_NOOPERATICNA IPMSG_BR_ENTRY IPMSG_EXIT is allowed p=NULL /n" ) ;
        return 1;
    }
    else if ( ( p!=NULL) & & ( mode!=IPMSG_NOOPERATION) & & ( mode!=IPMSG_BR_ENTRY) & & ( mode!=IPMSG_BR_EXIT) )
         client= * p;

//打开广播
    if ( setsockopt ( udp_fd, SOL_SOCKET, SO_BROADCAST, & broadcast_en, broadcast_len) < 0 )
    {
        perror ( "setsockopt error" ) ;
        exit ( 1) ;
    }
    switch ( mode)
    {
        case IPMSG_NOOPERATION:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, NULL ) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, ( struct sockaddr * ) & udp_addr, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_BR_ENTRY:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, ( struct sockaddr * ) & udp_addr, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_BR_EXIT:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, ( struct sockaddr * ) & udp_addr, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_ANSENTRY:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_SENDMSG:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_SENDMSG_OPT:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_RECVMSG:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_GETFILEDATA:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_RELEASEFILES:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        case IPMSG_GETDIRFILES:
        sprintf ( msg_buf, "1:%d:%s:%s:%d:%s" , msg_id, use, group, mode, msg) ;
        sendto ( udp_fd, msg_buf, strlen ( msg_buf) , 0, & client, sizeof ( struct sockaddr ) ) ;
        break ;
        default :
        printf ( "no match mode !/n" ) ;
        break ;
    }
     broadcast_en= 0;

// 关掉广播
    if ( setsockopt ( udp_fd, SOL_SOCKET, SO_BROADCAST, & broadcast_en, broadcast_len) < 0 )
    {
        perror ( "setsockopt error" ) ;
        exit ( 1) ;
    }
    printf ( "msg send ok ! /n" ) ;
    return 0;
}     

 

通过上边的报文就可以实现消息的传递,可以发起文件、文件夹的传输,传输文件时,首先需要通过UDP报文联络,在UDP报文联络好之后,随即发起TCP文件传输,文件传输是不带格式的。IPMSG的一个难点就是文件夹的传输。今天就写这里,而却也做到这里。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值