- From: "Oon Heok Kee" <oonheokkee78 AT hotmail.com>
 
- To: discussion AT sctp.de
 
- Subject: [SCTP-Discussion] input/output error
 
- Date: Tue Sep  3 14:57:01 2002
 
- List-id: SCTP Discussions <discussion.sctp.de>
 
 
Hi,
	I've made use of what I understood from the echo-client codes that Thomas 
had corrected and tried to implement my knowledge on the echo-server program 
instead.
	It's now able to receive, but the moment it tries to echo back to the 
client, it gives an "input/output error". Can someone advise on what could 
be wrong? I've attached the client and server codes as attachments so that 
all of you can have a look. Thank you!!!
Cheers,
Oon, Heok Kee
_________________________________________________________________
Chat with friends online, try MSN Messenger: 
http://messenger.msn.com
/* Echo Client Example */
/* SCTP client */
/* Compile this file with "gcc -o sctp_client sctp_client.c -Wall 
-lsctpsocket -lsctp -lglib -lstdc++ -lpthread". */
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#include <sys/types.h>
#include <sys/time.h>
#include <ext_socket.h>
#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sctp.h>
#define RCVBUFSIZE 1024 /* Size of receive buffer */
#define OUTSTREAM 3 /* Number of out-bound streams */
#define INSTREAM 2 /* Number of in-bound streams */
void DieWithError(char *errorMessage)
{
  perror(errorMessage);
  exit(1);
}
int main(int argc, char *argv[])
{
  int sock; /* Socket descriptor */
  struct sockaddr_in echoServAddr;/* Echo server address */
  unsigned short echoServPort; /* Echo server port */
  char *servIP; /* Server IP address (dotted quad) */
  char *echoString; /* String to send to echo server */
  char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
  unsigned int echoStringLen; /* Length of string to echo */
  int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv() and total 
bytes read */
  struct sctp_initmsg sim;
  struct sctp_sndrcvinfo *sinfo;
  struct msghdr msg[1];
  struct cmsghdr *cmsg;
  struct iovec iov[1];
  char cbuf[sizeof(*cmsg) + sizeof(*sinfo) + sizeof(*echoString)];
  struct sctp_event_subscribe events;
  /* Test for correct number of arguments */
  if ((argc < 3) || (argc > 4)) {
     fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo 
Port>]\n",argv[0]);
     exit(1);
  }
  servIP = argv[1]; /* First arg: server IP address (dotted quad) */
  echoString = argv[2]; /* Second arg: string to echo */
  if (argc == 4)
     echoServPort = atoi(argv[3]); /* Use given port, if any */
  else
     /* 7 is the well-known port for the echo service */
     echoServPort = 7;
  printf("\nCreating socket... ");
  /* Create a reliable, stream socket using TCP */
  if ((sock = ext_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0)
  {
     DieWithError("socket() failed");
  }
  printf("Socket created.\n\n");
  (&sim)->sinit_num_ostreams = OUTSTREAM;
  (&sim)->sinit_max_instreams = INSTREAM;
  (&sim)->sinit_max_attempts = 3;
  (&sim)->sinit_max_init_timeo = 30;
  /* Setting socket options */
  if (ext_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, &sim, sizeof(sim)) < 
0)
  {
     DieWithError("setsockopt() failed");
  }
  memset((char*)&events,0,sizeof(events));
  events.sctp_data_io_event = 1;
  if (ext_setsockopt(sock, IPPROTO_SCTP, SCTP_SET_EVENTS, &events, 
sizeof(events)) < 0) {
     DieWithError("setsockopt() failed");
  }
  memset(msg, 0, sizeof(*msg));
  msg->msg_control = cbuf;
  msg->msg_controllen = sizeof(struct cmsghdr) + sizeof(struct 
sctp_sndrcvinfo);
  msg->msg_flags = 0;
  (&iov[0])->iov_base = echoString;
  (&iov[0])->iov_len = strlen(echoString);
  msg->msg_iov = (struct iovec*)&iov;
  msg->msg_iovlen = 1;
  cmsg = (struct cmsghdr *)cbuf;
  sinfo = (struct sctp_sndrcvinfo *)(cmsg + 1);
  cmsg->cmsg_len = sizeof(struct cmsghdr) + sizeof(struct sctp_sndrcvinfo);
  cmsg->cmsg_level = IPPROTO_SCTP;
  cmsg->cmsg_type = SCTP_SNDRCV;
  sinfo->sinfo_assoc_id = 0;
  sinfo->sinfo_stream = 2; /* streamNumber */
  sinfo->sinfo_flags = 0;
  sinfo->sinfo_ppid = 0x12345678; /* ppid */
  sinfo->sinfo_context = (uint32_t)NULL;
  sinfo->sinfo_timetolive = (unsigned int)-1;
  /* Construct the server address structure */
  /* Zero out structure */
  memset(&echoServAddr, 0, sizeof(echoServAddr));
  echoServAddr.sin_family = AF_INET; /* Internet address family */
  /* Server IP address */
  echoServAddr.sin_addr.s_addr = inet_addr(servIP);
  echoServAddr.sin_port = htons(echoServPort); /* Server port */
  printf("Connecting to server at %s:%u ... ", servIP, echoServPort);
  /* Establish the connection to the echo server */
  if (ext_connect(sock, (struct sockaddr *) &echoServAddr, 
sizeof(echoServAddr)) < 0)
     DieWithError("connect() failed");
  printf("Connected.\n\n");
  echoStringLen = strlen(echoString); /* Determine input length */
  printf("Sending message \"%s\" to server... ", echoString);
  /* Send the string to the server */
  if (ext_sendmsg(sock, msg, 0) < 0)
     DieWithError("send() failed!");
  printf("Message sent.\n\n");
  /* Receive the same string back from the server */
  totalBytesRcvd = 0;
  (&iov[0])->iov_base = echoBuffer;
  (&iov[0])->iov_len  = sizeof(echoBuffer);
  msg->msg_iov = (struct iovec*)&iov;
  msg->msg_iovlen = 1;
  msg->msg_control = cbuf;
  msg->msg_controllen = sizeof(cbuf);
  msg->msg_flags = 0;
  msg->msg_name = NULL;
  msg->msg_namelen = 0;
  printf("Receiving echo from server... ");
  printf("Received: "); /* Setup to print the echoed string */
  while (totalBytesRcvd < echoStringLen)
  {
     /* Receive up to the buffer size (minus 1 to leave space for a null 
terminator) bytes from the sender */
     if ((bytesRcvd = ext_recvmsg(sock, msg, 0)) <= 0) /*echoBuffer, 
RCVBUFSIZE - 1, 0)) <= 0)*/
        DieWithError("recv() failed or conn. closed prematurely");
        totalBytesRcvd += bytesRcvd; /* Keep tally of total bytes */
        echoBuffer[bytesRcvd] = '\0'; /* Terminate the string! */
        printf(echoBuffer); /* Print the echo buffer */
        if(msg->msg_controllen > 0) {
           cmsg = CMSG_FIRSTHDR(msg);
           if((cmsg != NULL) && (cmsg->cmsg_level == IPPROTO_SCTP) && 
(cmsg->cmsg_type == SCTP_SNDRCV)) {
              sinfo = (struct sctp_sndrcvinfo*)CMSG_DATA(cmsg);
              printf("Stream ID:   %d\n",sinfo->sinfo_stream);
              printf("Protocol ID: %08x\n",sinfo->sinfo_ppid);
           }
        }
     }
  printf("\n\n"); /* Print a final linefeed */
  ext_close(sock);
  usleep(100000);
  exit(0);
}
/**** Echo Server Example ****/
/* SCTP server */
/* Compile this file with "gcc -o sctp_server sctp_server.c -Wall 
-lsctpsocket -lsctp -lglib -lstdc++ -lpthread". */
#include <stdio.h> /* for printf() and fprintf() */
#include <sys/socket.h> /* for socket(), bind(), and connect() */
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h> /* for atoi() */
#include <string.h> /* for memset() */
#include <unistd.h> /* for close() */
#include <sys/types.h>
#include <sys/time.h>
#include <ext_socket.h>
#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sctp.h>
#define MAXPENDING 5 /* Maximum outstanding connection requests */
#define RCVBUFSIZE 1024 /* Size of receive buffer */
#define OUTSTREAM 3 /* Number of out-bound streams to initialise */
#define INSTREAM 3 /*Number of in-bound streams to initialise */
void DieWithError(char *errorMessage)
{
        perror(errorMessage);
        exit(1);
}
void HandleSCTPClient(int clntSocket)
{
       char echoBuffer[RCVBUFSIZE];
        int recvMsgSize; /* Size of received message */
        struct msghdr msg[1];
        struct cmsghdr *cmsg;
        struct sctp_sndrcvinfo *sri;
        struct iovec iov[1];
	size_t cmsglen = sizeof(struct cmsghdr) + sizeof(struct sctp_sndrcvinfo) + 
sizeof(echoBuffer);
        char cbuf[cmsglen];
        memset(msg, 0, sizeof(*msg));
        msg->msg_control = cbuf;
        msg->msg_controllen = cmsglen;
        msg->msg_flags = 0;
        printf("Receiving message from client...\n\n");
        (&iov[0])->iov_base = echoBuffer;
        (&iov[0])->iov_len = sizeof(echoBuffer);
        msg->msg_iov = (struct iovec*)&iov;
        msg->msg_iovlen = 1;
        cmsg = (struct cmsghdr *)cbuf;
        sri = (struct sctp_sndrcvinfo *)(cmsg + 1);
        cmsg->cmsg_len = cmsglen;
        cmsg->cmsg_level = IPPROTO_SCTP;
        cmsg->cmsg_type = SCTP_SNDRCV;
        sri->sinfo_assoc_id = 0;
        sri->sinfo_stream = 1;
        sri->sinfo_flags = 0;
        sri->sinfo_ppid = 0x12345678;
        sri->sinfo_context = (uint32_t)NULL;
        sri->sinfo_timetolive = (unsigned int)-1;
        printf("Message received: ");
        do{
                recvMsgSize = 0;
                msg->msg_flags = 0;
                msg->msg_control = cbuf;
                msg->msg_controllen = cmsglen;
                msg->msg_name = NULL;
                msg->msg_namelen = 0;
                if ((recvMsgSize = ext_recvmsg(clntSocket, msg, 0)) <= 0)
                {
                        DieWithError("recvmsg() failed");
                } else {
                        printf("recvMsgSize = %d\n\n", recvMsgSize);
                        echoBuffer[recvMsgSize] = '\0';
                        printf("%s", echoBuffer);
                }
                (&iov[0])->iov_base = echoBuffer;
                (&iov[0])->iov_len = sizeof(echoBuffer);
                msg->msg_iov = (struct iovec*)&iov;
                msg->msg_iovlen = 1;
                msg->msg_flags = 0;
               msg->msg_control = cbuf;
               msg->msg_controllen = cmsglen - sizeof(echoBuffer);
               msg->msg_name = NULL;
               msg->msg_namelen = 0;
                if (ext_sendmsg(clntSocket, msg, 0) < 0)
                        DieWithError("send() failed");
        } while (recvMsgSize > 0);
        printf("\n\nClosing connection... ");
        ext_close(clntSocket); /* Close client socket */
        printf("Connection closed.\n\n");
}
int main(int argc, char *argv[])
{
        int servSock; /* Socket descriptor for server */
        int clntSock; /* Socket descriptor for client */
        struct sockaddr_in echoServAddr; /* Local address */
        struct sockaddr_in echoClntAddr; /* Client address */
        unsigned int clntLen; /* Length of client address */
        unsigned short echoServPort; /* Server port */
        struct sctp_initmsg sim;
        struct sctp_event_subscribe events;
        if (argc != 2) /* Test for correct number of arguments */
        {
                fprintf(stderr, "Usage: %s <Server Port>\n", argv[0]);
                exit(1);
        }
        echoServPort = atoi(argv[1]); /* First arg: local port */
        printf("\nCreating socket... ");
        /* Create socket for incoming connections */
        if ((servSock = ext_socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP)) < 0)
                DieWithError("socket() failed");
        printf("Socket created.\n\n");
        /* Construct local address structure */
        /* Zero out structure */
        memset(&echoServAddr, 0, sizeof(echoServAddr));
        echoServAddr.sin_family = AF_INET;/* Internet addr. family */
        /* Any incoming interface */
        echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        echoServAddr.sin_port = htons(echoServPort); /* Local port */
        /* To initialise the number of in and out streams needed with the 
client */
       (&sim)->sinit_num_ostreams = OUTSTREAM;
       (&sim)->sinit_max_instreams = INSTREAM;
       (&sim)->sinit_max_attempts = 3;
       (&sim)->sinit_max_init_timeo = 30;
       if (ext_setsockopt(servSock, IPPROTO_SCTP, SCTP_INITMSG, &sim, 
sizeof(sim)) < 0)
       {
               DieWithError("setsockopt() failed");
               exit(1);
       }
        memset((char *)&events, 0, sizeof(events));
        events.sctp_data_io_event = 1;
	if (ext_setsockopt(servSock, IPPROTO_SCTP, SCTP_SET_EVENTS, &events, 
sizeof(events)) < 0)
                DieWithError("setsockopt() failed");
        printf("Binding to address... ");
        /* Bind to the local address */
	if (ext_bind(servSock, (struct sockaddr *) &echoServAddr, 
sizeof(echoServAddr)) < 0)
                DieWithError("bind() failed");
        printf("Address bounded.\n\n");
        /* Mark the socket so it will listen for incoming conn. */
        printf("Waiting for connection... ");
        if (ext_listen(servSock, MAXPENDING) < 0)
                DieWithError("listen() failed");
        for (;;) /* Run forever */
        {
                /* Set the size of the in-out parameter */
                clntLen = sizeof(echoClntAddr);
                /* Wait for a client to connect */
		if ((clntSock = ext_accept(servSock, (struct sockaddr *) &echoClntAddr, 
&clntLen)) < 0)
                        DieWithError("accept() failed");
                printf("Connected.\n\n");
                /* clntSock is connected to a client! */
                printf("Handling client %s\n\n", 
inet_ntoa(echoClntAddr.sin_addr));
                HandleSCTPClient(clntSock);
        }
}
- [SCTP-Discussion] input/output error, Oon Heok Kee, 09/03/2002
 
Archive powered by MHonArc 2.6.19+.