SCTP 库的简述和代码 (5)

用户接口设计app

设计需求:socket

接口API, RFC4960有规范, 基本上按照设计就能够了. 须要考虑的地方时, 1. 提供简化的接口,方便懒人. 2. 因为设计此SCTP库的目的是用于p2p传输, 因此,要考虑方便服务于p2p的库.ide

 

定义了一个以下回调函数表,  当有链接请求或数据到达时, 回调.函数

typedef struct sctp_call_back_ {
    sctp_pkg_snd_fn sctp_pkg_snd;
    data_received_fn data_received_cb;
    sctp_assoc_up_fn   assoc_up_cb;
    sctp_assoc_down_fn assoc_down_cb;
    sctp_retrieve_fn retrieve_cb;
    sctp_debug_fn debug_cb;
}sctp_call_back;ui

sctp_pkg_snd 是可选的参数, 若是你想对数据的发送方法作特殊处理, 能够覆盖库的缺省动做. 若是不设置此函数,那么, 将直接发送到对方IP地址:接收SCTP包的UDP端口.debug

data_received_cb, 有SCTP包到达时被触发.设计

retrieve_cb, sctp一个流断掉后, 没有确认的数据包能够用此函数提取, 保证高可靠性.接口

 

接口API:ip

入参, udp_port, 用于sctp流的udp端口. ctx, 可选, 用户提供的上下文, 对sctp库来讲,透明,方便上层应用.路由

返回成功/失败

BOOL sctp_init(sctp_call_back* sctp_cb, uint16 udp_port, void *ctx)

返回 instance, 起一个sctp的服务socket, 至关于listen
int sctp_listen(uint16 local_port, uint32 local_ip);

 

返回assoc id, 至关与connect

peer_id是可选项, 16字节.  用来和p2p库一块儿使用时, 此peer_id包含了对方的IP地址,端口等. 对方能够是一个有公共网IP的节点,此时, 根据peer_id能够获得对方地址直接使用. 当对方在一个私网中,此id可用来请p2p库帮忙路由数据包到达对方. 简单的说, 在p2p网中, 重要的是peer_id,有了它就能够找到对方, 此peer_id起到的做用就是IP地址的做用.

int sctp_connect(int instance, uint32 peer_ip,  uint16 dst_port, uchar *peer_id);

 

至关于send

int sctp_send_data(int assoc_id, uchar *buf, uint16 len)

例子:

初始化:

入口参数是用来传输sctp数据的udp端口号. 若是是在局域网中,这个端口可能和NAT后的端口不同,简单的说,就是本机服务端口:
int app_sctp_init(uint16 sctp_udp_port)
{
 sctp_call_back call_cb;

 memset(&call_cb, 0, sizeof(call_cb));
 call_cb.assoc_down_cb = assoc_down;
 call_cb.assoc_up_cb = assoc_up;
 call_cb.data_received_cb = data_rcvd;
 call_cb.sctp_pkg_snd = send_sctp_pkg;
 sctp_init(&call_cb, VIDEO_UDP_PORT, p2p_hdl);
 return TRUE;
}

 

回调函数:
int assoc_down(int assoc_id, int reason)
{
 if (vedioDlg->videoAssoc == assoc_id)
 {
  vedioDlg->videoAssoc = 0;
  vedioDlg->ShowWindow(SW_HIDE);
  memset(guiDlg->active_video_peer, 0, 16);
 }
 return 0;
}

int assoc_up(int instance, int assoc_id, unsigned short peer_port, int in_stream, int out_stream)

 vedioDlg->videoAssoc = assoc_id;
 vedioDlg->ShowWindow(SW_SHOW);
 return 0;
}

int data_rcvd(int assoc_id, unsigned char *buf, unsigned short len,  unsigned short stream_id, int protocol, int part_data) {  if (vedioDlg->isCaptureStarted == FALSE)  {   // user has not click start video yet   sctp_consume_data(assoc_id, buf, len);   return len;  }   PostMessage(guiDlg->m_hWnd, WM_VIDEODATA, (WPARAM)buf, (LPARAM)len);  return len; }

相关文章
相关标签/搜索