SCTP 通信是区别于TCP通信和UDP通信外的一种传输层协议通信,兼具了TCP和UDP的部分优点,比如SCTP不是以字节为单位传输,而是以数据块为单位传输;SCTP传输的消息是可靠的,不像UDP那样是不可靠的;SCTP传输可以使用多路径,不像TCP那样一个socket只能传输一个路径的信息等;除此之外,SCTP通信相比TCP和UDP通信更多了一层安全保障,那就是四步握手。要使 ARM64架构的板子支持SCTP通信,是需要打开内核选项的,不像x86那样默认支持SCTP:
重新编译内核文件Image并替换,板子就支持SCTP通信了,但是在实际通信过程中发现了诸多问题,至今尚未解决,目前只完成了建立socket bind() listen()等步骤,还未能正常进行通信,后续有更新进度的话我会编辑此帖子进行更新。
安装SCTP第三方软件库有两个方法,一是通过apt安装:
或是直接从支持网站中下载源码包进行编译,下载lksctp-tools-1.0.18并解压:
- ./bootstrap
- ./configure
- make install实际测试这两种方式区别不大,因此就按照apt安装的方式进行,首先编写server端代码,依次进行socket() bind() listen()等操作:
复制代码
- if((sockfd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) == -1)
- {
- printf(" create socket error: %s (errno :%d)n",strerror(errno),errno);
- return 0;
- }
- printf("========= sockfd = %d=========n" , sockfd);
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(SERVER_PORT);
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
- inet_pton(AF_INET , SERVER_IP , &servaddr.sin_addr);
- int ret;
- ret = bind(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
- printf("========= bind = %d=========n" , ret);
- struct sctp_event_subscribe events;
- bzero(&events,sizeof(events));
- events.sctp_data_io_event = 1;
- ret = setsockopt(sockfd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(events));
- printf("========= setsockopt = %d=========n" , ret);
- ret = listen(sockfd,LISTENQ);
- printf("========= listen = %d=========n" , ret);
复制代码
创建发送线程:
- pthread_create(&id1 , NULL , Thread_Sctp_Send , NULL);
- void *Thread_Sctp_Send(void * args)
- {
- struct sctp_sndrcvinfo sri;
- while(1)
- {
- char msg[MAXLINE] = "Interesting7777777";
- sctp_sendmsg(sockfd,msg,sizeof(msg),(struct sockaddr *)&cliaddr,800,sri.sinfo_ppid,(sri.sinfo_flags),sri.sinfo_stream,0,0);
- sleep(1);
- }
- }
复制代码
主循环中进行循环接收:
- while(1)
- {
- socklen_t len=sizeof(struct sockaddr_in);
- size_t rd_sz=sctp_recvmsg(sockfd,rdbuf,sizeof(rdbuf),(struct sockaddr *)&cliaddr,&len,&sri,&flag);
- printf("=========server rdbuf = %s =========n" , rdbuf);
- }
复制代码
然后是client端的代码,与server端大同小异:
- int flag = 0;
- if((sockfd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) == -1)
- {
- printf(" create socket error: %s (errno :%d)n",strerror(errno),errno);
- return 0;
- }
- printf("========= sockfd = %d =========n" , sockfd);
-
- struct sockaddr_in servaddr;
- bzero(&servaddr,sizeof(servaddr));
- servaddr.sin_family=AF_INET;
- servaddr.sin_port=htons(SERVER_PORT);
- inet_pton(AF_INET , SERVER_IP , &servaddr.sin_addr);
- struct sctp_event_subscribe events;
- bzero(&events,sizeof(events));
- events.sctp_data_io_event=1;
- int ret = setsockopt(sockfd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(events));
- printf("========= setsockopt = %d=========n" , ret);
- ret = connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr));
- printf("========= connect = %d=========n" , ret);
- // if(flag == 0)
- // sctp_cli(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
- // else
- // sctp_cli_all(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
- if(ret >= 0)
- pthread_create(&id1 , NULL , Thread_Sctp_Recv , NULL);
- char rdbuf[MAXLINE] = "Interesting666666";
- int len = SCTP_MAXLINE , rd_sz=strlen(rdbuf);
- struct sctp_sndrcvinfo sri;
复制代码
主循环发送:
- while(1)
- {
- sctp_sendmsg(sockfd,rdbuf,rd_sz,(struct sockaddr *)&servaddr,len,sri.sinfo_ppid,(sri.sinfo_flags),sri.sinfo_stream,0,0);
- sleep(1);
- }
复制代码
接收线程:
- void *Thread_Sctp_Recv(void * args)
- {
- char rdbuf[MAXLINE];
- struct sctp_sndrcvinfo sri;
- int flag;
- while(1)
- {
- socklen_t len = sizeof(struct sockaddr_in);
- size_t rd_sz=sctp_recvmsg(sockfd,rdbuf,sizeof(rdbuf),(struct sockaddr *)&cliaddr,&len,&sri,&flag);
- printf("=========client rdbuf = %s =========n" , rdbuf);
- }
- }
复制代码
实际运行中,server端的socket() bind() listen()返回值均正常,但是接收循环中陷入了无数据但一直打印接收的死循环中,这是很严重的问题,需要后续跟进:
0
|
|
|
|