服务端代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/sctp.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 4096
#define PORT 6007
#define LISTENQ 100
#define SCTP_MAX_STREAM 15
int main(int argc,char **argv) {
int sockfd,msg_flags;
char readbuf[BUFSIZE + 1];
struct sockaddr_in serveraddr,clientaddr;
struct sctp_sndrcvinfo sri;
struct sctp_event_subscribe events;
int stream_increment = 1;
socklen_t len;
size_t rd_sz;
if (argc == 2)
stream_increment = atoi(argv[1]);
if ((sockfd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) < 0) {
printf("sockfd error %s\n",strerror(errno));
exit(1);
}
struct sctp_initmsg sim;
bzero(&sim,sizeof(struct sctp_initmsg));
sim.sinit_num_ostreams = SCTP_MAX_STREAM;
if (setsockopt(sockfd,IPPROTO_SCTP,SCTP_INITMSG,&sim,sizeof(struct sctp_initmsg)) < 0) {
printf("setsockopt error: %s\n",strerror(errno));
exit(1);
}
bzero(&serveraddr,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(PORT);
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr)) < 0) {
printf("bind error %s\n",strerror(errno));
exit(1);
}
bzero(&events,sizeof(events));
events.sctp_data_io_event = 1;
if (setsockopt(sockfd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(events)) < 0) {
printf("setsockopt error %s\n",strerror(errno));
exit(1);
}
if (listen(sockfd,LISTENQ) < 0) {
printf("listen error %s\n",strerror(errno));
exit(1);
}
for (; ;) {
len = sizeof(struct sockaddr_in);
if ((rd_sz = sctp_recvmsg(sockfd,readbuf,sizeof(readbuf),(struct sockaddr*)&clientaddr,&len,&sri,&msg_flags)) < 0) {
printf("sctp_recvmsg error %s\n",strerror(errno));
exit(1);
}
if (stream_increment) {
sri.sinfo_stream++;
if (sri.sinfo_stream >= SCTP_MAX_STREAM) {
sri.sinfo_stream = 0;
}
}
if (sctp_sendmsg(sockfd,readbuf,rd_sz,(struct sockaddr*)&clientaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0) != rd_sz) {
printf("sctp_sendmsg error %s\n",strerror(errno));
exit(1);
}
}
}
客户端代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <netinet/sctp.h>
#define PORT 6007
#define BUFSIZE 4096
#define SCTP_MAX_STREAM 15
void client_echo_all(int fd,struct sockaddr* to,socklen_t tolen) {
struct sctp_event_subscribe events;
bzero(&events,sizeof(struct sctp_event_subscribe));
events.sctp_data_io_event = 1;
if (setsockopt(fd,IPPROTO_SCTP,SCTP_EVENTS,&events,sizeof(struct sctp_event_subscribe)) < 0) {
printf("setsockopt error: %s\n",strerror(errno));
exit(1);
}
struct sctp_initmsg sim;
bzero(&sim,sizeof(struct sctp_initmsg));
sim.sinit_num_ostreams = SCTP_MAX_STREAM;
if (setsockopt(fd,IPPROTO_SCTP,SCTP_INITMSG,&sim,sizeof(struct sctp_initmsg)) < 0) {
printf("setsockopt error: %s\n",strerror(errno));
exit(1);
}
char sendbuf[BUFSIZE + 1],recvbuf[BUFSIZE + 1];
int n;
struct sctp_sndrcvinfo sri;
socklen_t len = tolen;
int msg_flags;
while ((n = read(STDIN_FILENO,sendbuf,BUFSIZE)) > 0) {
if (sendbuf[n - 1] == '\n') {
sendbuf[n - 1] = '\0';
--n;
}
for (int i = 0; i < SCTP_MAX_STREAM; ++i) {
snprintf(sendbuf + n,sizeof(sendbuf) - n,".msg.%d 1",i);
if (sctp_sendmsg(fd,sendbuf,sizeof(sendbuf),to,tolen,0,0,i,0,0) != sizeof(sendbuf)) {
printf("sctp_sendmsg error: %s\n",strerror(errno));
exit(1);
}
snprintf(sendbuf + n,sizeof(sendbuf) - n,".msg.%d 2",i);
if (sctp_sendmsg(fd,sendbuf,sizeof(sendbuf),to,tolen,0,0,i,0,0) != sizeof(sendbuf)) {
printf("sctp_sendmsg error: %s\n",strerror(errno));
exit(1);
}
}
for (int i = 0; i < 2 * SCTP_MAX_STREAM; ++i) {
if ((n = sctp_recvmsg(fd,recvbuf,sizeof(recvbuf),to,&len,&sri,&msg_flags)) < 0) {
printf("get the message from server failed %s\n",strerror(errno));
exit(1);
}
printf("From stream: %d sequence: %d (assoc:0x%x)",sri.sinfo_stream,sri.sinfo_ssn,(unsigned)sri.sinfo_assoc_id);
printf("%.*s\n",n,recvbuf);
}
}
}
int main(int argc,char **argv) {
if (argc != 2) {
printf("please add <ip address>\n");
exit(1);
}
int sockfd;
if ((sockfd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) < 0) {
printf("socket error: %s\n",strerror(errno));
exit(1);
}
struct sockaddr_in serveraddr;
bzero(&serveraddr,sizeof(struct sockaddr_in));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(PORT);
if (inet_pton(AF_INET,argv[1],&serveraddr.sin_addr) <= 0) {
printf("inet_pton error: %s\n",strerror(errno));
exit(1);
}
client_echo_all(sockfd,(struct sockaddr*)&serveraddr,sizeof(struct sockaddr));
return 0;
}
运行: