Reputation: 1
Here's my client code:
#include "unp.h"
int main(int argc, char **argv)
{
int sock_fd;
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)
{
printf("Echoing messages to all streams\n");
echo_to_all = 1;
}
sock_fd = 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);
bzero(&evnts, sizeof(evnts));
evnts.sctp_data_io_event = 1;
Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
&evnts, sizeof(evnts));
if (echo_to_all == 0)
sctpstr_cli(stdin, sock_fd, (SA *)&servaddr, sizeof(servaddr));
else
sctpstr_cli_echoall(stdin, sock_fd, (SA *)&servaddr, sizeof(servaddr));
Close(sock_fd);
return (0);
}
I execute the command with arg echo
so that it will go into the function sctpstr_cli_echoall
whose code is as followed. This function is going to send one message in every possible stream to the server.
void 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),
(SA *)&peeraddr, &len,
&sri, &msg_flags);
printf("From str:%d seq:%d (assoc:0x%x):",
sri.sinfo_stream, sri.sinfo_ssn,
(unsigned int)sri.sinfo_assoc_id);
printf("%.*s\n", rd_sz, recvline);
}
}
}
The code of server is as follows. It just sends back whatever it received to the client as an echo server. I execute the command with arg 0, which indicates that it will send back the data in the same stream as it received the data.
void 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),
(SA *)&peeraddr, &len,
&sri, &msg_flags);
printf("From str:%d seq:%d (assoc:0x%x):",
sri.sinfo_stream, sri.sinfo_ssn,
(unsigned int)sri.sinfo_assoc_id);
printf("%.*s\n", rd_sz, recvline);
}
}
}
int sctp_get_no_strms(int sock_fd, sctp_assoc_t sinfo_assoc_id)
{
int retsz;
struct sctp_status status;
retsz = sizeof(status);
bzero(&status, sizeof(status));
status.sstat_assoc_id = sinfo_assoc_id;
Getsockopt(sock_fd, IPPROTO_SCTP, SCTP_STATUS,
&status, &retsz);
return (status.sstat_outstrms);
}
I run the program and the client output as followed, shows I received the first packet twice.
Hope anyone could help me solve the problem?
Upvotes: 0
Views: 92