SCTP客户端与服务器

  1 /**
  2  * @brief - Send a message, using advanced SCTP features
  3  * The sctp_sendmsg() function allows you to send extra information to a remote application.
  4  * Using advanced SCTP features, you can send a message through a specified stream,
  5  * pass extra opaque information to a remote application, or define a timeout for the particular message.
  6  *
  7  * @header - #include <netinet/sctp.h>
  8  *
  9  * @return ssize_t - The number of bytes sent, or -1 if an error occurs (errno is set).
 10  *
 11  * @ERRORS
 12  * EBADF
 13  *     An invalid descriptor was specified.
 14  * EDESTADDRREQ
 15  *     A destination address is required.
 16  * EFAULT
 17  *     An invalid user space address was specified for a parameter.
 18  * EMSGSIZE
 19  *     The socket requires that the message be sent atomically, but the size of the message made this impossible.
 20  * ENOBUFS
 21  *     The system couldn't allocate an internal buffer. The operation may succeed when buffers become available.
 22  * ENOTSOCK
 23  *     The argument s isn't a socket.
 24  * EWOULDBLOCK
 25  *     The socket is marked nonblocking and the requested operation would block.
 26  */
 27 ssize_t sctp_sendmsg(int s,                             /*! Socket descriptor. */
 28                      const void *msg,         /*! Message to be sent. */
 29                      size_t len,                     /*! Length of the message. */
 30                      struct sockaddr *to, /*! Destination address of the message. */
 31                      socklen_t tolen,         /*! Length of the destination address. */
 32                      uint32_t ppid,             /*! An opaque unsigned value that is passed to the remote end in each user message.
 33                                                                         The byte order issues are not accounted for and this information is passed opaquely
 34                                                                           by the SCTP stack from one end to the other. */
 35                      uint32_t flags,             /*! Flags composed of bitwise OR of these values:
 36                                                                          MSG_UNORDERED
 37                                                                              This flag requests the unordered delivery of the message.
 38                                                                              If the flag is clear, the datagram is considered an ordered send.
 39                                                                          MSG_ADDR_OVER
 40                                                                              This flag, in one-to-many style, requests the SCTP stack to override the primary destination address.
 41                                                                          MSG_ABORT
 42                                                                              This flag causes the specified association to abort -- by sending
 43                                                                              an ABORT message to the peer (one-to-many style only).
 44                                                                          MSG_EOF
 45                                                                              This flag invokes the SCTP graceful shutdown procedures on the specified association.
 46                                                                              Graceful shutdown assures that all data enqueued by both endpoints is successfully
 47                                                                              transmitted before closing the association (one-to-many style only). */
 48                      uint16_t stream_no,     /*! Message stream number -- for the application to send a message.
 49                                                                          If a sender specifies an invalid stream number, an error indication is returned and the call fails. */
 50                      uint32_t timetolive,    /*! Message time to live in milliseconds.
 51                                                                          The sending side expires the message within the specified time period
 52                                                                          if the message has not been sent to the peer within this time period.
 53                                                                          This value overrides any default value set using socket option.
 54                                                                          If you use a value of 0, it indicates that no timeout should occur on this message. */
 55                      uint32_t context);        /*! An opaque 32-bit context datum.
 56                                                                          This value is passed back to the upper layer if an error occurs while sending a message,
 57                                                                          and is retrieved with each undelivered message. */
 58 
 59 #include <stdio.h>  
 60 #include <stdlib.h>  
 61 #include <string.h>  
 62 #include <unistd.h>  
 63 #include <time.h>  
 64 #include <sys/socket.h>  
 65 #include <sys/types.h>  
 66 #include <netinet/in.h>  
 67 #include <netinet/sctp.h>  
 68 //#include "common.h"  
 69 #define MAX_BUFFER  1024  
 70 #define MY_PORT_NUM 19000  
 71 #define LOCALTIME_STREAM    0  
 72 #define GMT_STREAM   1  
 73 
 74 int main()
 75 {
 76     int listenSock, connSock, ret;
 77     struct sockaddr_in servaddr;
 78     char buffer[MAX_BUFFER + 1];
 79     time_t currentTime;
 80 
 81     /* Create SCTP TCP-Style. Socket */
 82     listenSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP ); // 注意这里的IPPROTO_SCTP
 83     /* Accept connections from any interface */
 84     bzero( (void *)&servaddr, sizeof(servaddr) );
 85     servaddr.sin_family = AF_INET;
 86     servaddr.sin_addr.s_addr = htonl( INADDR_ANY );
 87     servaddr.sin_port = htons(MY_PORT_NUM);
 88     /* Bind to the wildcard address (all) and MY_PORT_NUM */
 89     ret = bind( listenSock,
 90                 (struct sockaddr *)&servaddr, sizeof(servaddr) );
 91     /* Place the server socket into the listening state */
 92     listen( listenSock, 5 );
 93     /* Server loop... */
 94     while( 1 )
 95     {
 96         /* Await a new client connection */
 97         connSock = accept( listenSock,
 98                            (struct sockaddr *)NULL, (int *)NULL );
 99         /* New client socket has connected */
100         /* Grab the current time */
101         currentTime = time(NULL);
102         /* Send local time on stream 0 (local time stream) */
103         snprintf( buffer, MAX_BUFFER, "%s
", ctime(currentTime) );
104         ret = sctp_sendmsg( connSock,
105                             (void *)buffer, (size_t)strlen(buffer),
106                             NULL, 0, 0, 0, LOCALTIME_STREAM, 0, 0 );
107         /* Send GMT on stream 1 (GMT stream) */
108         snprintf( buffer, MAX_BUFFER, "%s
",
109                   asctime( gmtime( currentTime ) ) );
110         ret = sctp_sendmsg( connSock,
111                             (void *)buffer, (size_t)strlen(buffer),
112                             NULL, 0, 0, 0, GMT_STREAM, 0, 0 );
113         /* Close the client connection */
114         close( connSock );
115     }
116     return 0;
117 }
118 
119 
120 #include <stdio.h>  
121 #include <stdlib.h>  
122 #include <string.h>  
123 #include <unistd.h>  
124 #include <sys/socket.h>  
125 #include <sys/types.h>  
126 #include <netinet/in.h>  
127 #include <netinet/sctp.h>  
128 #include <arpa/inet.h>  
129 //#include "common.h"  
130 #define MAX_BUFFER  1024  
131 #define MY_PORT_NUM 19000  
132 #define LOCALTIME_STREAM    0  
133 #define GMT_STREAM   1  
134 
135 int main()
136 {
137     int connSock, in, i, flags;
138     struct sockaddr_in servaddr;
139     struct sctp_sndrcvinfo sndrcvinfo;
140     struct sctp_event_subscribe events;
141     char buffer[MAX_BUFFER + 1];
142     /* Create an SCTP TCP-Style. Socket */
143     connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );
144     /* Specify the peer endpoint to which we'll connect */
145     bzero( (void *)&servaddr, sizeof(servaddr) );
146     servaddr.sin_family = AF_INET;
147     servaddr.sin_port = htons(MY_PORT_NUM);
148     servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
149     /* Connect to the server */
150     connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );
151     /* Enable receipt of SCTP Snd/Rcv Data via sctp_recvmsg */
152     memset( (void *)&events, 0, sizeof(events) );
153     events.sctp_data_io_event = 1;
154     setsockopt( connSock, SOL_SCTP, SCTP_EVENTS,
155                 (const void *)&events, sizeof(events) );
156     /* Expect two messages from the peer */
157     for (i = 0 ; i < 2 ; i++)
158     {
159         in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer),
160                            (struct sockaddr *)NULL, 0,
161                            &sndrcvinfo, &flags );
162         /* Null terminate the incoming string */
163         buffer[in] = 0;
164         if (sndrcvinfo.sinfo_stream == LOCALTIME_STREAM)
165         {
166             printf("(Local) %s
", buffer);
167         }
168         else if (sndrcvinfo.sinfo_stream == GMT_STREAM)
169         {
170             printf("(GMT  ) %s
", buffer);
171         }
172     }
173     /* Close our socket and exit */
174     close(connSock);
175     return 0;
176 }
原文地址:https://www.cnblogs.com/fengkang1008/p/4713223.html