文章目录

  • 1、概述
  • 2、接口模型
    • 2.1 一到一形式
    • 2.2 一到多形式
  • 3、sctp_bindx函数
  • 4、sctp_connectx函数
  • 5、sctp_getpaddrs函数
  • 6、sctp_freepaddrs函数
  • 7、sctp_getladdrs函数
  • 8、sctp_freelpaddrs
  • 9、sctp_sendmsg
  • 10、sctp_recvmsg
  • 11、sctp_opt_info
  • 12、sctp_peeloff函数
  • 13、shudown
  • 14、通知
  • 15、SCTP c/s程序
  • 16、SCTP一到多式流分回射服务器程序
  • 17、SCTP流分回射客户程序
  • 18、sctpstr_cli函数
  • 19、探究头端阻塞
  • 20、控制流的数目
  • 21、控制终结

1、概述

SCTP是一个较新的传输协议;是一个可靠的面向消息的协议;在端点之间提供多个流,并为多宿提供传输级支持;

2、接口模型

可分为:- 一到一套接字:对应一个单独的SCTP关联;- 一到多套接字:一个给定套接字从若干个同时在发送数据的远程UDP端点接收彼此交错的数据报;

在决定使用哪种接口形式时,考虑应用程序的因素

- 所编写的服务器程序是迭代的还是并发;
- 服务器希望管理多少套接字描述符;
- 优化关联建立的四路握手过程,使得能够在其中第三个分组交换用户数据,这一点很重要吗;
- 应用进程希望维护多少个连接状态;

2.1 一到一形式

该形式是为了方便将TCP应用程序移植到SCTP上;
- 任何套接字选项都必须由TCP转换成SCTP,常见的是TCP_NODELAY和TCP_MAXSEG,应该映射成SCTP_NODELAY和SCTP_MAXSEGO;
- SCTP保存消息边界,因而应用层消息边界并非必需;如:基于TCP的某个应用协议可能先执行一个双字节的write系统调用,给出消息的长度x,再调用一个x字节的write系统调用,写出消息数据本身;改用SCTP后,接收端SCTP将收到两个独立的消息也就是说得有两次read系统调用才能返回全部数据:第一次返回一个双字节数据,第二次返回一个x字节消息);
- 有些TCP应用进程使用半关闭来告知对端去往它的数据流已经结束;将这样的应用程序移植到SCTP需要额外重写应用层协议,让应用进程在应用数据流中告知对端该传输数据流已经结束;
- send能够以普通方式使用,使用sendto或sendmsg时,指定的任何地址都被认为是对目的地主地址的重写;【典型用法】:服务器启动后,打开一个套接字,bind一个地址,等待accept客户关联;客户启动后,打开一个套接字,并初始化与服务器的一个关联;若客户想服务器发送一个请求,服务器处理该请求后向客户发回一个应答;该循环持续到客户开始终止该关联为止;

2.2 一到多形式

【开发】:编写的服务器无需管理大量的套接字描述符,当个套接字描述符将代表多个关联,即一个UDP套接字能从多个客户接收消息;
在一到多式套接字上,用于标识单个关联的是一个关联标识(类型为sctp_ASSOC_T的值);

- 当一个客户关闭其关联时,其服务器自动关闭同一个关联,且内核中不再有该关联的状态;
- 四路握手的第三个或第四个分组中捎带用户数据的唯一办法就是使用一到多形式;
- 对于与它还没有关联存在的IP,任何以它为目的地的sendto、sendmsg或sctp_sendmsg将导致对主动打开的尝试,从而建立一个与该地址的新关联;该行为的发送与执行分组发送的这个应用进程是否曾调用过listen函数以请求被动打开无关;
- 用户必须使用sendto、sendmsg或sctp_sendmsg这3个分组发送函数,而不能使用send或write,除非已使用sctp_peeloff函数从一个一到多式套接字剥离出一个一到一式套接字;
- 任何时候调用其中任何一个分组发送函数时,所用的目的地址是由系统在关联建立阶段选定的主目的地址;除非调用者在所提供的sctp_sndrcvinfo中设置了MSG_ADDR_OVER;且必须伴随使用sendmsg或sctp_sendmsg函数;
- 关联事件可能被启用,因此要应用进程不要收到这些事件,使用SCTP_EVENTS显示禁止;默认下是sctp_data_io_event,它给recvmsg和sctp_recvmsg调用辅助数据;

上述为迭代服务器,许多关联的消息能够由单个控制线程处理;
在SCTP中,一个一到多套接字也能够结合使用sctp_peeloff函数以允许组合迭代服务器莫西和并发服务器模型;
- sctp_peeloff函数用于从一个一到多套接字剥离出某个特定的关联,独自构成一个一到一式套接字;
- 剥离出的关联所在的一到一套接字随后就可以遣送给它自己的线程,或者遣送给为它派生的进程;
- 与此同时,主线程继续在原来的套接字上以迭代方式处理来自任何剩余关联的消息,一到多式SCTP套接字是一个类型为SOCK_SEQPACKET,协议为IPPROTO_SCTP的网际网套接字;

3、sctp_bindx函数

#include <netinet/sctp.h>int sctp_bindx(int sockfd, const struct sockaddr *addr, int addrcnt, int flags);
/**
@func: 该函数允许SCTP套接字捆绑一个特定地址子集;
@param sockfd: socket函数返回的描述符;
@param addrs: 一个指向紧凑的地址列表的指针;
@param addrcnt: 指定地址个数;
@param flags: 指导sctp_bindx调用;
*/

sctp_bindx调用既可用于已绑定的套接字,也可用于未绑定的套接字;
【未绑定套接字】:sctp_bindx调用将把给定的地址集合捆绑到其上;
【已绑定套接字】:若指定SCTP_BINDX_ADD_ADDR则把额外的地址加入到套接字描述符,若指定SCTP_BINDX_REM_ADDR则从套接字描述符的已加入地址中移除给定的地址l;
如果在一个监听套接字上执行sctp_bindx调用,产生的关联将使用新的地址配置,已经存在的关联则不受影响;
传递给sctp_bindx的两个标志是互斥的,若同时指定,则调用失败返回的EINVALO;
所有套接字地址结构的端口号必须相同,且必须与已经绑定的端口号相匹配,否则调用就会失败,返回EINVAL;
若一个端点支持动态地址特性,指定SCTP_BINDX_ADD_ADDR或SCTP_BINDX_REM_ADDR标志调用sctp_bindx将导致该端点向对端发送一个合适的消息,
以修改对端的地址列表;由于增减一个己连接关联的地址只是一个可选的功能,因此不支持本功能的实现将返回EOPNOTSUPP;
【注意】:本功能正确操作要求两个端点都支持这个特性;本特性对于支持动态接口供给的系统可能有用;如:若调出一个新的以太网接口,那么应用进程可以指定SCTP_BINDX_ADD_ADDR标志在已经存在的连接上启动使用这个接口;

4、sctp_connectx函数

#include <netinet/sctp.h>int sctp_connectx(int sockfd, const struct sockaddr *addr, int addrcnt);
/**
@func: 函数用于连接到一个多宿对端主机;
@param addrs: 指定addrcnt个全部属于同一对端的地址,是一个紧凑的地址列表;SCTP栈使用其中一个或多个地址建立关联;
*/

5、sctp_getpaddrs函数

当SCTP使用getpeername时将仅仅返回主目的地址;
若需要直到对端的所有地址,则应该使用sctp_getpaddrs函数
#include <netinet/sctp.h>int sctp_getpaddrs(int sockfd, sctp_assoc_t id, struct sockaddr **addrs);
/**
@func: 获取对端的所有地址;
@param id: 是一到多式套接字的关联标识,而一到一式套接字会忽略该字段;
@param addrs: 地址指针,内容由本函数动态分配并填入的紧凑的地址列表;
【注意】:使用完后,应使用sctp_freepaddrs释放分配的资源;
*/

6、sctp_freepaddrs函数

#include <netinet/sctp.h>void sctp_freepaddrs(struct sockaddr *addrs);
/**
@func: 函数释放由sctp_getpaddrs函数分配的资源;
@param addrs: 指向sctp_getpaddrs的返回的数组的指针;
*/

7、sctp_getladdrs函数

#include <netinet/sctp.h>int sctp_getladdrs(int sockfd, sctp_addoc_t id, struct sockfaddr **addrs);
/**
@func: 用于获取属于某个关联的本地地址;
@param id: 一到多式套接字的关联标识,而一到一式套接字则会将其忽略;
@param addrs: 地址指针,内容为本函数动态分配并填入的紧凑的地址列表;
【注意】:使用完后,应使用sctp_freelpaddrs释放分配的资源;
*/

8、sctp_freelpaddrs

#include <netinet/sctp.h>void sctp_freeladdrs(struct sockaddr *addrs);
/**
@func: 释放由sctp_getlpaddrs分配的资源;
@param addr: sctp_getlpaddrs返回的地址数字的指针;
*/

9、sctp_sendmsg

#include <netinet/sctp.h>ssize_t sctp_sendmsg(int sockfd, const void *msg, size_t msggz, const struct sockaddr *to, socklen_t tolen,uint32_t ppid,uint32_t flags, uint16_t stream,uint32_t timetolive, uint32_t context);
/**
@func: 能够控制SCTP的各种特性;
@param msg: 指向一个长度为msgsz字节的缓冲区;
@param to: 内容发送的地点;
@param tolen: to中的地址长度;
@param ppid: 将随数据块传递的净荷协议标识符;
@param flags: 传递给SCTP栈,用以标识任何SCTP选项;
@param stream: 指定一个SCTP流号;
@param timetolive: 以毫秒为单位的消息的生命期,0为无限;
@param context: 指定可能有的用户上下文;用户上下文把通过消息通知机制收到的某次失败的消息发送与某个特定于应用的本地上下文关联;
*/

10、sctp_recvmsg

#include <netinet/sctp.h>ssize_t sctp_recvmsg(int sockfd, void *msg, size_t msgsz, struct sockaddr *from, socklen_t *fromlen, struct sctp_sndrcvinfo *sinfo, int *msg_flags);
/**
@func: 获取对端的地址及获取通常伴随recvmsg调用返回的msg_flags参数,可获取sctp_sndrcvinfo;
@param msg: 指向一个长度为msgsz字节的缓冲区;
@param from: 内容发送的地点;
@param fromlen: to中的地址长度;
@param msg_flags: 存放可能有的消息标志;
【注意】:若应用进程要接收sctp_sndrcbinfo,则要使用SCTP_EVENTS预订sctp_data_io_event;
*/

11、sctp_opt_info

#include <netinet/sctp.h>int sctp_opt_info(int sockfd, sctp_assoc_t assoc_id, int opt,void *arg, socklen_t *siz);
/**
@func: 允许套接字选项中使用出入变量的系统,将一个参数重新打包到合适的getsockopt调用中的库函数;
@param assoc_id: 给出可能存在的关联标识;
@param opt: SCTP的套接字选项;
@param arg: 套接字选项参数;
@param siz: 存放参数的大小;
*/

12、sctp_peeloff函数

#include <netinet/sctp.h>int sctp_peeloff(int sockfd, sctp_assoc_t id);
/**
@func: 把一到多式套接字的sockfd和待抽取的关联标识id传递给函数调用;
return: 新的套接字描述符,即一个与所请求关联对应的一到一式套接字描述符;
*/

13、shudown

SCTP不提供半关闭状态,对shutdown调用的反应不同于TCP端点;
当相互通信的两个SCTP端点中任何一个发起关联终止序列时,这两个端点都得把已排队的任何数据发送掉,然后关闭关联;
关联主动打开的发起端点改用shutdown而不是close的可能原因是:- 同一个端点可用于连接到一个新的对端端点;- 与TCP不同,新的套接字打开之前不必调用close;
SCTP允许一个端点调用shutdown,结束后,这个端点可重用原套接字连接到一个新的对端;
【注意】:如果这个端点没有等到SCTP关联终止序列结束,新的连接就会失败;shutdown中的howto参数:【SHUT_RD】:没有任何SCTP协议行为发生。【SHUT_WR】:禁止后续发送操作,激活SCTP关联终止过程,以此终止当前关联;【SHUT_RDWR】:禁止所有read、write操作,激活SCTP关联终止过程;

14、通知

SCTP用户可经由这些通知追踪相关关联的状态,由套接字描述符获取;
通知传递的是传输级的事件,包括网络状态变动、关联启动、远程操作错误一级消息不可递送;
用户可用recvmsg和sctp_recvmsg区分对端的数据和由事件产生的通知;
若返回的数据是一个事件通知,则两个函数返回的msg_flags将含有MSG_NOTIFICATION标志;该标志告知应用进程刚刚读入的消息不是来自对端的数据,而时来自本地SCTP栈的一个通知;【通知格式】:都是采用标签-长度-值,其中前8个字节给出通知的类型和总长度;开启sctp_data_io_event将导致每次读入用户数据都收到一个sctp_sndrcvinfo;
一般信息通过调用recvmsg作为辅助数据获取,应用程序可调用sctp_recvmsg,同样的信息将被填写到由某个指针指出的sctp_sndrcvinfo;
struct sctp_tlv{u_int16_t sn_type;u_int16_t sn_flags;u_int32_t sn_length;
};union sctp_notification{struct sctp_tlv sn_header;struct sctp_assoc_change sn_assoc_change;struct sctp_ paddr__change sn_paddr_change;struct sctp_remote_error sn_remote_error;struct sctp_send__failed sn_send_failed;struct sctp_shutdown_event sn_shutdown_event;struct sctp__adaption_event sn_adaption_event;struct sctp pdapi_event sn_pdapi_event ;
};

15、SCTP c/s程序

以下将编写一个一到多式SCTP客户/服务器程序:
- 客户从标准输入读入一行文本,并发送给服务器;该文本行遵循[#]text格式,#是在其上发送该文本消息的SCTP流号;
- 服务器从网络接收这个文本消息,把在其上到达消息的流号增1,再在新的流号上发送回同一个文本呢消息给客户;
- 客户从网络读入这行回射文本,并显示在标准输出上,内容包括流号、流序列号和文本串;

16、SCTP一到多式流分回射服务器程序

int main(int argc, char **argv) {int sfd, msg_flags;char readBuf[BUFFSIZE];struct sockaddr_in servaddr, cliaddr;struct sctp_sndrcvinfo sri;struct sctp_event_subscribe evnts;int stream_increment = 1;socklen_t len;size_t rd_sz;if(argc == 2)stream_increment = atoi(argv[1]);/* 创建一个SCTP一到多式套接字 */sfd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);/* 捆绑地址,对于多宿主机,这种捆绑意味着一个远程断点能够与这个本地主机任何一个路由* 地址建立关联并发送分组* */bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);bind(sfd, (struct sockaddr*)&servaddr, sizeof(servaddr));/* 预定sctp_data_io_event,从而允许服务器查看sctp_sndrcvinfo结构,* 服务器可从结构确定消息所在的流号* */bzero(&evnts, sizeof(evnts));evnts.sctp_data_io_event = 1;setsockopt(sfd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));listen(sfd, LISTENQ);while (1) {len = sizeof(struct sockaddr_in);/* 等待消息,服务器初始化客户套接字地址结构的大小,后阻塞在等待来自任何一个远程* 对端的消息上;* */rd_sz = sctp_recvmsg(sfd, readBuf, sizeof(readBuf),(struct sockaddr*)&cliaddr, &len, &sri, &msg_flags);/* 当有消息到达时,服务器检查stream_increment来确定是否需要增长流号;* 若设置了该标志,服务器就把消息的流号增1,若流号增长最大流号时,服务器就把流号重置为0* */if(stream_increment) {sri.sinfo_stream++;if(sri.sinfo_stream >=sctp_get_no_strms(sfd, (struct sockaddr*)&cliaddr, len))sri.sinfo_stream = 0;}/* 服务器使用来自sri结构的净荷协议ID、标志一级可能改动过的流号发送回消息本身* 服务器不希望得到关联通知,故禁止了向上传递消息到套接字缓冲区的所有事件;* 本服务器依赖于sctp_sndrcvinfo结构中的消息和cliaddr返回地址定位对端的关联地址并回射消息;* */sctp_sendmsg(sfd, readBuf, rd_sz,(struct sockaddr*)&cliaddr, len,sri.sinfo_ppid,sri.sinfo_flags, sri.sinfo_stream, 0, 0);}return 0;
}

17、SCTP流分回射客户程序

int main(int argc, char **argv) {int sfd;struct sockaddr_in servaddr;struct sctp_event_subscribe evnts;int echo_to_all = 0;if(argc < 2)err_quit("Missing host argument - use '%s host [echo]'\n", argv[0]);if(argc > 2) {err_quit("Echoing messages to all streams\n");echo_to_all = 1;}/* 创建一个sctp一到多式套接字 */sfd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);inet_pton(AF_INET, argv[1], &servaddr.sin_addr);    // 服务器地址从表达式转化成数值格式/* 客户显示设置其一到多式SCTP套接字的通知预订*/bzero(&evnts, sizeof(evnts));evnts.sctp_data_io_event = 1;setsockopt(sfd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(servaddr));if(echo_to_all == 0)sctpstr_cli(stdin, sfd, (struct sockaddr*)&servaddr, sizeof(servaddr));elsesctpstr_cli_echoall(stdin, sfd, (struct sockaddr*)&servaddr, sizeof(servaddr));close(sfd);return 0;
}

sctp_address_to_associd

sctp_assoc_t sctp_address_to_associd(int sock_fd, struct sockaddr *sa, socklen_t salen)
{struct sctp_paddrparams sp;socklen_t siz;siz = sizeof(struct sctp_paddrparams);bzero(&sp,siz);memcpy(&sp.spp_address,sa,salen);sctp_opt_info(sock_fd,0,SCTP_PEER_ADDR_PARAMS, &sp, &siz);return(sp.spp_assoc_id);
}

sctp_get_no_strms

int sctp_get_no_strms(int sock_fd,struct sockaddr *to, socklen_t tolen)
{socklen_t retsz;struct sctp_status status;retsz = sizeof(status);bzero(&status,sizeof(status));status.sstat_assoc_id = sctp_address_to_associd(sock_fd,to,tolen);getsockopt(sock_fd,IPPROTO_SCTP, SCTP_STATUS,&status, &retsz);return(status.sstat_outstrms);
}

18、sctpstr_cli函数

void sctpstr_cli(FILE *fp, int sockfd, struct sockaddr *to, socklen_t tolen) {struct sockaddr_in peeraddr;struct sctp_sndrcvinfo sri;char sendline[MAXLINE], recvline[MAXLINE];socklen_t len;int out_sz, rd_sz;int msg_flags;/* 将sri清0,并循环阻塞读取 */bzero(&sri, sizeof(sri));while (fgets(sendline, MAXLINE, fp) != NULL) {/* 检查输入格式 */if(sendline[0] != '[') {cout << "Error, line must be of the from '[streamnum]text'\n";continue;}/* 将请求的流号转成sri结构的sinfo_stream */sri.sinfo_stream = strtol(&sendline[1], NULL, 0);/* 初始化目的地址结构的长度以及用户数据的大小后,客户使用sctp_sendmsg函数发送消息 */out_sz = strlen(sendline);sctp_sendmsg(sockfd, sendline, out_sz, to,tolen, 0, 0, sri.sinfo_stream, 0, 0);/* 阻塞等待服务器的回射消息 */len = sizeof(peeraddr);rd_sz = sctp_recvmsg(sockfd, recvline, sizeof(recvline),(struct sockaddr*)&peeraddr, &len, &sri, &msg_flags);printf("From str:%d seq:%d (assoc:0x%x):",sri.sinfo_stream, sri.sinfo_ssn, (u_int)sri.sinfo_assoc_id);printf("%.*s", rd_sz, recvline);}
}

19、探究头端阻塞

SCTP中内部关联具有先后顺序的消息序列;
【避免仅使用单个TCP字节流导致的头端阻塞现象】:以流本身而不是以流所在关联为单位进行消息排序;

现象描述

头端阻塞发送在一个TCP分解丢失,导致后续分解不按序到达接受端;
当第一张图丢失时,客户将保持已不按序到达的所有数据,直到丢失的分节被重传并成功到达为止;


SCTP对流特性

SCTP该特性能够减少头端阻塞;
后续的图不受第一幅的影响;

#define SCTP_MAXLINE 800
#define SERV_MAX_SCTP_STRM 10void sctpstr_cli_echoall(FILE *fp, int sock_fd, struct sockaddr *to,socklen_t tolen) {struct sockaddr_in peeraddr;struct sctp_sndrcvinfo sri;char sendline[SCTP_MAXLINE], recvline[SCTP_MAXLINE];socklen_t len;int rd_sz, i, strsz;int msg_flags;bzero(sendline, sizeof(sendline));bzero(&sri, sizeof(sri));while (fgets(sendline, SCTP_MAXLINE - 9, fp) != NULL) {strsz = strlen(sendline);if(sendline[strsz -1] == '\n'){sendline[strsz-1] = '\0';strsz--;}for(i=0; i<SERV_MAX_SCTP_STRM; i++) {snprintf(sendline + strsz, sizeof(sendline) - strsz,".msg.%d", i);sctp_sendmsg(sock_fd, sendline, sizeof(sendline),to, tolen, 0, 0, i, 0, 0);}for(i=0; i<SERV_MAX_SCTP_STRM; ++i) {len = sizeof(peeraddr);rd_sz = sctp_recvmsg(sock_fd, recvline, sizeof(recvline),(struct sockaddr*)&peeraddr, &len, &sri, &msg_flags);printf("From str:%d seq:%d (assoc:0x%x):",sri.sinfo_stream, sri.sinfo_ssn, (u_int)sri.sinfo_assoc_id);printf("[%d]%s", rd_sz, recvline);}}
}

20、控制流的数目

如何在关联初始化阶段控制一个端点请求的流数目;
if(argc == 2) stream_increment = atoi(argv[1]);
sock_fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
/* 将sinit_num_ostream设置未期望请求的流数目 */
bzero(&initm, sizeoof(initm));
initm.sinit_num_ostream = SERV_MORE_STRMS_SCTP;
setsockopt(sock_fd, IPPROTO_SCTP, SCTP_INITMSG, &initm, sizeof(initm));

21、控制终结

如果服务器希望在发送完一个应答消息后终止一个关联:
- 可在与该消息对应的sctp_sndrcvinfo结构的sinfo_flags字段中设置WSG_EOF标志;该标志使所发送消息被客户确认之后,相应关联也被终止;
- 可把MSG_ABORT标志应用于sinfo_flags字段。该标志将以ABORT块迫使立即终止关联;SCTP的ABORT块类似TCP的RST分节,能够无延迟地中止任何关联,尚未发送的任何数据都被丢弃;

服务器程序应答同时终止关联的改动部分

while(1) {len = sizeof(struct sockaddr_in);rd_sz = sctp_recvmgs(sock_fd, readbuf, sizeof(readbuf));if(stream_increment) {sri.sinfo_stream++;if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd, (struct sockaddr*)&cliaddr, len))sri.sinfo_stream = 0;}sctp_sendmsg(sock_fd, readbuf, rd_sz, (struct sockaddr*)&cliaddr, len, sri.sinfo_ppid, (sri.sinfo_flags | MSG_EOF), sri.sinfo_stream, 0, 0);
}

客户程序预先终止关联的改动部分

if(echo_to_all == 0)sctpstr_cli(stdin, sock_fd, (struct sockaddr*)&servaddr, sizeof(servaddr));
elsesctpstr_cli_echoall(stdin, sock_fd, (struct sockaddr*)&servaddr, sizeof(servaddr));
/* 客户准备一个信息座位关联中止的用户错误起因,后以MSG_ABORT调用sctp_sendmsg函数;该标志导致一发送一个ABORT块,从而立即终止当前关联,该ABORT块包含用户发起错误起因代码*/
strcpy(byemsg, "goodbye");
sctp_sendmsg(sock_fd, byemsg, strlen(byemsg), (struct sockaddr*)&servaddr, sizeof(servaddr), 0, MSG_ABORT, 0, 0, 0);
/* 即使关联中止,仍得关闭套接字描述符以释放与关联的系统资源 */
close(sock_fd);

【UNIX网络编程】|【07】SCTP协议探究相关推荐

  1. 《UNIX网络编程 卷1:套接字联网API(第3版)》——第2章 传输层:TCP、UDP和SCTP 2.1概述...

    本节书摘来自异步社区<UNIX网络编程 卷1:套接字联网API(第3版)>一书中的第2章,第2.1节,作者:[美]W. Richard Stevens , Bill Fenner , An ...

  2. UNIX网络编程—SCTP编译运行错误及解决

    UNIX网络编程-SCTP编译运行错误及解决 环境 ubuntu 14.04 64bits unpv13e 问题1 'redefinition of 'struct in_pktinfo' 解决办法1 ...

  3. UNIX网络编程.卷1,套接字联网API(第3版)(中文版)(Stevens经典著作,两位顶级网络编程专家应邀执笔修订)...

    UNIX网络编程.卷1,套接字联网API(第3版)(中文版)(Stevens经典著作,两位顶级网络编程专家应邀执笔修订) 基本信息 原书名: Unix Network Programming, Vol ...

  4. 网编编程必看书籍:unix网络编程

    unix网络编程被誉为圣经,该书主要讲socket套接字相关,socket API,从底层剖析网络编程.网络编程中需要用到的一些经典函数,多路复用函数,这些都值得去反复学习研究. 目录: 录 Part ...

  5. 再读Socket编程——《UNIX网络编程(卷一)》学习点滴

    原先曾以Socket编程为入口开始自己的新的学习,毕竟未曾致用,时至今日已比较生疏.借着阅读<UNIX网络编程(卷一)>(简称UNPv1)的机会,正好复习一番,而且希望将新的感受记录下来. ...

  6. UNIX网络编程之旅-配置unp.h头文件环境

    最近在学习Unix网络编程(UNP),书中steven在处理网络编程时只用了一个#include "unp.h"  相当有个性并且也很便捷 于是我把第三版的源代码编译实现了这个过程 ...

  7. WinSock API网络编程——TCP/IP协议详解

     WinSock API网络编程--TCP/IP协议(http://www.impcas.ac.cn/usr/lujun/browse.asp?id=winsock_tcp)            ...

  8. UNIX网络编程学习笔记(代码超详细解析)(持续更新)

    1. 其他函数准备 1. TCP 回射服务器程序: str_echo 函数 #include "unp.h"void str_echo(int sockfd) {ssize_t n ...

  9. Unix网络编程 chart

    前言 在最初接触网络这一领域的时候,就是傻傻地抱着一本TCP/IP协议详解来学习,主要学习协议的原理并研究协议相关的算法,大家都知道协议纯理论的学习是比较枯燥和复杂的,看着看着就睡着了.由于项目需要, ...

  10. unix网络编程之简介和运输层TCP/UDP

    前言:本文只介绍了有关UNIX网络编程的理论知识,具体的应用和例子在稍后的博文中将更新 第一章  简介 一个简单的服务器程序步骤: 说明:1.创建TCP套接口 2.捆绑服务器的众所周知端口 3.把套接 ...

最新文章

  1. DIY一个DNS查询器:了解DNS协议
  2. python中的print()、str()和repr()的区别
  3. 4月22日(牛马不对嘴)
  4. 一个古帝国做产品的故事
  5. 汇编 --- 栈结构的妙用
  6. String、StringBuuffer、StringBuilder三者的区别
  7. js 当前日期增加自然月
  8. iCMS v8.0.0多终端内容管理系统
  9. 萌新的Python练习菜鸟100例(十一)生兔子练习
  10. MarkdownPad-显示Awesomium 已停止工作,This view has carshed!错误
  11. 视频教程-思科CCNP专题系列⑨:交换机安全-思科认证
  12. 【解决方案】SkeyeARS及SkeyeIVMS技术助力地铁安防视频监控系统建设
  13. MTk kernel启动流程
  14. 计算机专业就业前景分析
  15. php代码审计靶场,RIPS --代码审计靶场(第一关)-华盟网
  16. 国家税务总局河南省电子税务局中,交契税时,报房屋属地税务机关必填的解决方法
  17. vue不具名插槽与具名插槽
  18. “前浪”微博财报里的悲喜两极
  19. .cfg\.dat\.mak(持续补充)
  20. matlab zf预编码,多用户MIMO系统中各种波束成型预编码性能比较(ZF,BD,MMSE,SLNR,MF,SVD)...

热门文章

  1. 测试显卡用什么软件最好,显卡测试用什么软件 怎么测试显卡性能
  2. MAC中安装Navicat Premium
  3. Qt是什么?Qt简介(非常全面)
  4. SpringBoot微服务项目打包流程
  5. 单词发音网页 (文本处理 python)
  6. java flv 转swf_nginx-http-flv-module flv拉流错误整理
  7. 内网代理流量:Socks5协议原理分析和编程
  8. jmail邮件服务器,ASP Dimac W3 JMail 邮件收发组件函数(JMail使用详解)
  9. Office 2007 SP3 正试版补丁包下载
  10. android打电话录音软件,Android uni-app实现音视频通话