SCTP编程

SCTP编程1 简介 SCTP 是为了在 IP 网上传输信令而由 IETF 的信令传输工作组 SIGTRAN 提出的传输层协议 RFC2960 RFC4960 和 TCP UDP 相比 UDP 是无连接的传输协议 它能满足低延迟的要求 但是它却无法保证可靠传输 TCP 能保证数据可靠传输 但是它也不能完全符合信令传输

  • 多宿性(multi-homing)

    多宿是指一个SCTP 端点可以通过多个IP地址到达,这样两个SCTP端点在建立了关联后,数据可以通过不    同的物理通路进行传送。也就是说,当一条通路坏掉后,可以通过另一条通路到达对端。

  • 多流性(multi-streaming)

    由于采用多个流进行传输而且各个流相互独立,这样当一个流中的数据包需要重传,其他流中的数据可以    继续传输, 解决了在TCP单流中容易出现的队头阻塞现象(head-of-line).

  • 安全机制
  • 一对一
  • 一对多

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include "common.h"

int main()
{

  int connSock, in, i, ret, flags;
  struct sockaddr_in servaddr;
  struct sctp_status status;
  struct sctp_sndrcvinfo sndrcvinfo;
  struct sctp_event_subscribe events;
  struct sctp_initmsg initmsg;
  char buffer[MAX_BUFFER+1];

  /* Create an SCTP TCP-Style Socket */
  connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  /* Specify that a maximum of 5 streams will be available per socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( connSock, IPPROTO_SCTP, SCTP_INITMSG,
                     &initmsg, sizeof(initmsg) );

  /* Specify the peer endpoint to which we'll connect */
  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(MY_PORT_NUM);
  servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );

  /* Connect to the server */
  ret = connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
  memset( (void *)&events, 0, sizeof(events) );
  events.sctp_data_io_event = 1;
  ret = setsockopt( connSock, SOL_SCTP, SCTP_EVENTS,
                     (const void *)&events, sizeof(events) );

  /* Read and emit the status of the Socket (optional step) */
  in = sizeof(status);
  ret = getsockopt( connSock, SOL_SCTP, SCTP_STATUS,
                     (void *)&status, (socklen_t *)&in );

  printf("assoc id = %d\n", status.sstat_assoc_id );
  printf("state = %d\n", status.sstat_state );
  printf("instrms = %d\n", status.sstat_instrms );
  printf("outstrms = %d\n", status.sstat_outstrms );

  /* Expect two messages from the peer */

  for (i = 0 ; i < 2 ; i++) {

    in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer),
                        (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags );

    if (in > 0) {

      buffer[in] = 0;
      if (sndrcvinfo.sinfo_stream == LOCALTIME_STREAM) {

        printf("(Local) %s\n", buffer);
      } else if (sndrcvinfo.sinfo_stream == GMT_STREAM) {

        printf("(GMT ) %s\n", buffer);
      }
    }

  }

  /* Close our socket and exit */
  close(connSock);

  return 0;
}

















































































#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include "common.h"

int main()
{

  int listenSock, connSock, ret;
  struct sockaddr_in servaddr;
  struct sctp_initmsg initmsg;
  char buffer[MAX_BUFFER+1];
  time_t currentTime;

  /* Create SCTP TCP-Style Socket */
  listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  /* Accept connections from any interface */
  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
  servaddr.sin_port = htons(MY_PORT_NUM);

  ret = bind( listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Specify that a maximum of 5 streams will be available per socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( listenSock, IPPROTO_SCTP, SCTP_INITMSG,
                     &initmsg, sizeof(initmsg) );

  /* Place the server socket into the listening state */
  listen( listenSock, 5 );

  /* Server loop... */
  while( 1 ) {

    /* Await a new client connection */
    printf("Awaiting a new connection\n");
    connSock = accept( listenSock, (struct sockaddr *)NULL, (int *)NULL );

    /* New client socket has connected */

    /* Grab the current time */
    currentTime = time(NULL);

    /* Send local time on stream 0 (local time stream) */
    snprintf( buffer, MAX_BUFFER, "%s\n", ctime(&currentTime) );
    ret = sctp_sendmsg( connSock, (void *)buffer, (size_t)strlen(buffer),
                         NULL, 0, 0, 0, LOCALTIME_STREAM, 0, 0 );

    /* Send GMT on stream 1 (GMT stream) */
    snprintf( buffer, MAX_BUFFER, "%s\n", asctime( gmtime( &currentTime ) ) );
    ret = sctp_sendmsg( connSock, (void *)buffer, (size_t)strlen(buffer),
                         NULL, 0, 0, 0, GMT_STREAM, 0, 0 );

    /* Close the client connection */
    close( connSock );

  }

  return 0;
}





































































 

  • 多宿性(multi-homing)

    多宿是指一个SCTP 端点可以通过多个IP地址到达,这样两个SCTP端点在建立了关联后,数据可以通过不    同的物理通路进行传送。也就是说,当一条通路坏掉后,可以通过另一条通路到达对端。

  • 多流性(multi-streaming)

    由于采用多个流进行传输而且各个流相互独立,这样当一个流中的数据包需要重传,其他流中的数据可以    继续传输, 解决了在TCP单流中容易出现的队头阻塞现象(head-of-line).

  • 安去机制
  • 一对一
  • 一对多

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
#include "common.h"

int main()
{

  int connSock, in, i, ret, flags;
  struct sockaddr_in servaddr;
  struct sctp_status status;
  struct sctp_sndrcvinfo sndrcvinfo;
  struct sctp_event_subscribe events;
  struct sctp_initmsg initmsg;
  char buffer[MAX_BUFFER+1];

  /* Create an SCTP TCP-Style Socket */
  connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  /* Specify that a maximum of 5 streams will be available per socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( connSock, IPPROTO_SCTP, SCTP_INITMSG,
                     &initmsg, sizeof(initmsg) );

  /* Specify the peer endpoint to which we'll connect */
  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(MY_PORT_NUM);
  servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );

  /* Connect to the server */
  ret = connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
  memset( (void *)&events, 0, sizeof(events) );
  events.sctp_data_io_event = 1;
  ret = setsockopt( connSock, SOL_SCTP, SCTP_EVENTS,
                     (const void *)&events, sizeof(events) );

  /* Read and emit the status of the Socket (optional step) */
  in = sizeof(status);
  ret = getsockopt( connSock, SOL_SCTP, SCTP_STATUS,
                     (void *)&status, (socklen_t *)&in );

  printf("assoc id = %d\n", status.sstat_assoc_id );
  printf("state = %d\n", status.sstat_state );
  printf("instrms = %d\n", status.sstat_instrms );
  printf("outstrms = %d\n", status.sstat_outstrms );

  /* Expect two messages from the peer */

  for (i = 0 ; i < 2 ; i++) {

    in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer),
                        (struct sockaddr *)NULL, 0, &sndrcvinfo, &flags );

    if (in > 0) {

      buffer[in] = 0;
      if (sndrcvinfo.sinfo_stream == LOCALTIME_STREAM) {

        printf("(Local) %s\n", buffer);
      } else if (sndrcvinfo.sinfo_stream == GMT_STREAM) {

        printf("(GMT ) %s\n", buffer);
      }
    }

  }

  /* Close our socket and exit */
  close(connSock);

  return 0;
}

















































































#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include "common.h"

int main()
{

  int listenSock, connSock, ret;
  struct sockaddr_in servaddr;
  struct sctp_initmsg initmsg;
  char buffer[MAX_BUFFER+1];
  time_t currentTime;

  /* Create SCTP TCP-Style Socket */
  listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  /* Accept connections from any interface */
  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
  servaddr.sin_port = htons(MY_PORT_NUM);

  ret = bind( listenSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );

  /* Specify that a maximum of 5 streams will be available per socket */
  memset( &initmsg, 0, sizeof(initmsg) );
  initmsg.sinit_num_ostreams = 5;
  initmsg.sinit_max_instreams = 5;
  initmsg.sinit_max_attempts = 4;
  ret = setsockopt( listenSock, IPPROTO_SCTP, SCTP_INITMSG,
                     &initmsg, sizeof(initmsg) );

  /* Place the server socket into the listening state */
  listen( listenSock, 5 );

  /* Server loop... */
  while( 1 ) {

    /* Await a new client connection */
    printf("Awaiting a new connection\n");
    connSock =













































转载于:https://my.oschina.net/alphajay/blog/4727

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226536.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午10:40
下一篇 2026年3月16日 下午10:41


相关推荐

  • python中return的用法

    python中return的用法python 中 return 的用法 1 return 语句就是把执行结果返回到调用的地方 并把程序的控制权一起返回程序运行到所遇到的第一个 return 即返回 退出 def 块 不会再运行第二个 return 例如 defhaha x y ifx y returnx yprint haha 1 1 结果 这种 return 传参会返回元组 1 2 2 但是

    2026年3月20日
    2
  • 80. Remove Duplicates from Sorted Array II

    80. Remove Duplicates from Sorted Array II

    2022年4月2日
    56
  • 中国国家航天局:探月工程四期还有三次任务「建议收藏」

    中国国家航天局:探月工程四期还有三次任务「建议收藏」中国国家航天局:探月工程四期还有三次任务

    2022年4月21日
    58
  • redis中RDB和AOF的区别

    redis中RDB和AOF的区别1 前言最近在项目中使用到 Redis 做缓存 方便多个业务进程之间共享数据 由于 Redis 的数据都存放在内存中 如果没有配置持久化 redis 重启后数据就全丢失了 于是需要开启 redis 的持久化功能 将数据保存到磁盘上 当 redis 重启后 可以从磁盘中恢复数据 redis 提供两种方式进行持久化 一种是 RDB 持久化 原理是将 Reids 在内存中的数据库记录定时 dump 到磁盘上的 RDB 持久化 另外一

    2026年3月19日
    2
  • phpsotrm 2021激活码3月最新在线激活

    phpsotrm 2021激活码3月最新在线激活,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    50
  • 企业发卡源码+教程[通俗易懂]

    企业发卡源码+教程[通俗易懂]介绍:程序对接了易支付接口,后台增加商铺模板搭建教程:准备服务器《空间主机》+域名+上传源码解压,删除压缩包。修改数据库内容位置:application/database.php然后进入数据库,导入数据库文件,你的域名+admin=后台后台账号:admin后台网盘下载地址:http://kekewl.cc/elCdqYEXaIA图片:…

    2022年7月14日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号