- Subject: Error when build apps SCTP
- From: Thanh Nguyen <ht22.pt@xxxxxxxxx>
- Date: Tue, 22 Mar 2011 16:11:23 +0700
Hi,my name Thanh Nguyen.Student of University of Science Ho Chi Minh
City Viet Nam.I have one problem with SCTP API.
I have source code one example client server SCTP. (Attach).But when
build with gcc (using command gcc client.c -o client) was error as:
"'union sctp_notificationâ has no member named âsn_typesâ
And I check struct sctp_notification but sn_types is member of this
struct.Why error?
If you have example same it, and paper abount SCTP API.Please send to
me.Thanks a lot.
Source example,I take it from Oracle example.Code server build ok.
I have install LKSCTP, Fedora 13,GCC.
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* To enable socket features used for SCTP socket. */
#define _XPG4_2
#define __EXTENSIONS__
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <netinet/sctp.h>
#include <netdb.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <sys/errno.h>
#include <sys/param.h>
#include <sys/poll.h>
#include <arpa/inet.h>
#define BUFLEN 1024
static void
usage(char *a0)
{
fprintf(stderr, "Usage: %s <addr>\n", a0);
}
/*
* Read from the network.
*/
static void
readit(void *vfdp)
{
int fd;
ssize_t n;
char buf[BUFLEN];
struct msghdr msg[1];
struct iovec iov[1];
struct cmsghdr *cmsg;
struct sctp_sndrcvinfo *sri;
char cbuf[sizeof (*cmsg) + sizeof (*sri)];
union sctp_notification *snp;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
fd = *(int *)vfdp;
/* Initialize the message header for receiving */
memset(msg, 0, sizeof (*msg));
msg->msg_control = cbuf;
msg->msg_controllen = sizeof (*cmsg) + sizeof (*sri);
msg->msg_flags = 0;
cmsg = (struct cmsghdr *)cbuf;
sri = (struct sctp_sndrcvinfo *)(cmsg + 1);
iov->iov_base = buf;
iov->iov_len = BUFLEN;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
while ((n = recvmsg(fd, msg, 0)) > 0) {
/* Intercept notifications here */
if (msg->msg_flags & MSG_NOTIFICATION) {
snp = (union sctp_notification *)buf;
printf("[ Receive notification type %u ]\n",
snp->sn_types);
continue;
}
msg->msg_control = cbuf;
msg->msg_controllen = sizeof (*cmsg) + sizeof (*sri);
printf("[ Receive echo (%u bytes): stream = %hu, ssn = %hu, "
"flags = %hx, ppid = %u ]\n", n,
sri->sinfo_stream, sri->sinfo_ssn, sri->sinfo_flags,
sri->sinfo_ppid);
}
if (n < 0) {
perror("recv");
exit(1);
}
close(fd);
exit(0);
}
#define MAX_STREAM 64
static void
echo(struct sockaddr_in *addr)
{
int fd;
u_char buf[BUFLEN];
ssize_t n;
int perr;
pthread_t tid;
struct cmsghdr *cmsg;
struct sctp_sndrcvinfo *sri;
char cbuf[sizeof (*cmsg) + sizeof (*sri)];
struct msghdr msg[1];
struct iovec iov[1];
int ret;
struct sctp_initmsg initmsg;
struct sctp_event_subscribe events;
/* Create a one-one SCTP socket */
if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) == -1) {
perror("socket");
exit(1);
}
/*
* We are interested in association change events and we want
* to get sctp_sndrcvinfo in each receive.
*/
events.sctp_association_event = 1;
events.sctp_data_io_event = 1;
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &events,
sizeof (events));
if (ret < 0) {
perror("setsockopt SCTP_EVENTS");
exit(1);
}
/*
* Set the SCTP stream parameters to tell the other side when
* setting up the association.
*/
memset(&initmsg, 0, sizeof(struct sctp_initmsg));
initmsg.sinit_num_ostreams = MAX_STREAM;
initmsg.sinit_max_instreams = MAX_STREAM;
initmsg.sinit_max_attempts = MAX_STREAM;
ret = setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg,
sizeof(struct sctp_initmsg));
if (ret < 0) {
perror("setsockopt SCTP_INITMSG");
exit(1);
}
if (connect(fd, (struct sockaddr *)addr, sizeof (*addr)) == -1) {
perror("connect");
exit(1);
}
/* Initialize the message header structure for sending. */
memset(msg, 0, sizeof (*msg));
iov->iov_base = buf;
msg->msg_iov = iov;
msg->msg_iovlen = 1;
msg->msg_control = cbuf;
msg->msg_controllen = sizeof (*cmsg) + sizeof (*sri);
msg->msg_flags = 0;
memset(cbuf, 0, sizeof (*cmsg) + sizeof (*sri));
cmsg = (struct cmsghdr *)cbuf;
sri = (struct sctp_sndrcvinfo *)(cmsg + 1);
cmsg->cmsg_len = sizeof (*cmsg) + sizeof (*sri);
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
sri->sinfo_ppid = 1;
/* Start sending to stream 0. */
sri->sinfo_stream = 0;
/* Create a thread to receive network traffic. */
perr = pthread_create(&tid, NULL, (void *(*)(void *))readit, &fd);
if (perr != 0) {
fprintf(stderr, "pthread_create: %d\n", perr);
exit(1);
}
/* Read from stdin and then send to the echo server. */
while ((n = read(fileno(stdin), buf, BUFLEN)) > 0) {
iov->iov_len = n;
if (sendmsg(fd, msg, 0) < 0) {
perror("sendmsg");
exit(1);
}
/* Send the next message to a different stream. */
sri->sinfo_stream = (sri->sinfo_stream + 1) % MAX_STREAM;
}
pthread_cancel(tid);
close(fd);
}
int
main(int argc, char **argv)
{
struct sockaddr_in addr[1];
struct hostent *hp;
int error;
if (argc < 2) {
usage(*argv);
exit(1);
}
/* Find the host to connect to. */
hp = getipnodebyname(argv[1], AF_INET, 0, &error);
if (hp == NULL) {
fprintf(stderr, "host not found\n");
exit(1);
}
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = hp->h_addr_list[0];
addr->sin_port = htons(5000);
echo(addr);
return (0);
}
[Linux OMAP]
[Linux USB Devel]
[Video for Linux]
[Linux Audio Users]
[Photo]
[Yosemite News]
[Yosemite Photos]
[Free Online Dating]
[Linux Kernel]
[Linux SCSI]
[XFree86]