Beispiel #1
1
int main(int argc,char **argv)
{
	int sock_fd;
	int msg_flags;	// 記錄要傳送訊息時的相關設定,包括association...
	char readbuf[BUFFERSIZE];
	struct sockaddr_in cliaddr, servaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	socklen_t len;
	size_t rd_sz;	// size_t指的就是unsigned long
	int ret_value=0;
	struct sockaddr *laddrs;	// 用來記錄local addresses
	struct sockaddr *paddrs;
	union sctp_notification *snp;		// 用來轉換傳送過來的訊息
	struct sctp_shutdown_event *sse;	// 當傳送過來的是shutdown event,則可以用這一個指標指到傳送過來的資料
	struct sctp_assoc_change *sac;
	struct sctp_paddr_change *spc;
	struct sctp_remote_error *sre;
	struct sctp_send_failed *ssf;
#ifdef UN_MOD
	struct sctp_adaptation_event *ae;
#else
	struct sctp_adaption_event *ae;
#endif
	struct sctp_pdapi_event *pdapi;
	int close_time = 30;
	const char *str;

	if (argc < 2) {
		printf("Error, use %s [list of addresses to bind]\n",argv[0]);
		exit(-1);
	}
	// 建立socket的型態為SCTP的one-to-many的型態
	sock_fd = Socket(AF_INET,SOCK_SEQPACKET, IPPROTO_SCTP);
	if (sock_fd == -1) {
		printf("socket error\n");
		exit(-1);
	}

	// 初始化要bind的server資料,連續加入多個要綁的ip address
	int i;
	for (i=1;i<argc;i++) {
		memset(&servaddr,0,sizeof(servaddr));
		servaddr.sin_family = AF_INET;
		inet_pton(AF_INET,argv[i],&servaddr.sin_addr);	// 把socket與此ip綁在一起
		servaddr.sin_port = htons(SERV_PORT);

		// 把這一個ip與socket綁在一起
		if ((ret_value=sctp_bindx(sock_fd,(struct sockaddr*) &servaddr,1,SCTP_BINDX_ADD_ADDR))==-1) {
			printf("Can't bind the address %s\n",argv[i]);
			exit(-1);
		}
		else
		{
			// 無論如何一定會bind成功,因為,若給錯的ip,則會bind此host端的所有ip
			printf("Bind %s success!!\n",argv[i]);
		}
	}

	// 設定事件
	bzero(&evnts,sizeof(evnts));
	evnts.sctp_data_io_event=1;	// Enable sctp_sndrcvinfo to come with each recvmsg,否則就接收不到對方的資訊了
	evnts.sctp_shutdown_event=1;	// 喔耶!當client端shutdown時,會通知server
	evnts.sctp_association_event=1;	// 監測
	evnts.sctp_address_event = 1;
	evnts.sctp_send_failure_event = 1;
	evnts.sctp_peer_error_event = 1;
	evnts.sctp_partial_delivery_event = 1;
#ifdef UN_MOD
	evnts.sctp_adaptation_layer_event = 1;
#else
	evnts.sctp_adaption_layer_event = 1;
#endif
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_EVENTS,&evnts,sizeof(evnts));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_AUTOCLOSE,&close_time,sizeof(close_time));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}

	// 設定多少個client可以連線
	ret_value = listen(sock_fd,LISTENQ);
	if (ret_value == -1) {
		printf("listen error\n");
		exit(-1);
	}

	printf("start wait...\n");
	for (;;) {
		memset(readbuf,0,sizeof(readbuf));
		len = sizeof(struct sockaddr_in);
		rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);
		//========================================================================
		// test the sctp_getladdrs function - start
		ret_value = sctp_getladdrs(sock_fd,sri.sinfo_assoc_id,&laddrs);
		printf("The sctp_getladdrs return value is %d\n",ret_value);
		// test the sctp_getladdrs function - end
		// test the sctp_getpaddrs function - start
		ret_value = sctp_getpaddrs(sock_fd,sri.sinfo_assoc_id,&paddrs);
		printf("The sctp_getpaddrs return value is %d\n",ret_value);
		// test the sctp_getpaddrs function - end
		//========================================================================
		if (msg_flags & MSG_NOTIFICATION) {	// 表示收到一個事件通告,而非一個資料
			snp = (union sctp_notification *) readbuf;
			switch (snp->sn_header.sn_type) {
				case SCTP_SHUTDOWN_EVENT:
					sse = &snp->sn_shutdown_event;
					printf("SCTP_SHUTDOWN_EVENT: assoc=0x%x\n",(uint32_t) sse->sse_assoc_id);
					break;
				case SCTP_ASSOC_CHANGE:
					sac = &snp->sn_assoc_change;
					switch (sac->sac_state) {
						case SCTP_COMM_UP:
							printf("COMMUNICATION UP\n");
							break;
						case SCTP_COMM_LOST:
							printf("COMMUNICATION LOST\n");
							break;
						case SCTP_RESTART:
							printf("RESTART\n");
							break;
						case SCTP_SHUTDOWN_COMP:
							printf("SHUTDOWN COMPLETE\n");
							break;
						case SCTP_CANT_STR_ASSOC:
							printf("CAN'T START ASSOC\n");
							break;
						default:
							printf("UNKNOW\n");
							break;
					}
					break;
				case SCTP_PEER_ADDR_CHANGE:
					spc = &snp->sn_paddr_change;
					switch(spc->spc_state) {
						case SCTP_ADDR_AVAILABLE:
							str = "ADDRESS AVAILABLE";
							break;
						case SCTP_ADDR_UNREACHABLE:
							str = "ADDRESS UNREACHABLE";
							break;
						case SCTP_ADDR_REMOVED:
							str = "ADDRESS REMOVED";
							break;
						case SCTP_ADDR_ADDED:
							str = "ADDRESS ADDED";
							break;
						case SCTP_ADDR_MADE_PRIM:
							str = "ADDRESS MADE PRIMARY";
							break;
						case SCTP_ADDR_CONFIRMED:
							str = "ADDRESS MADE CONFIRMED";
							break;
						default:
							str = "UNKNOW";
							break;
					}
					printf("SCTP_PEER_ADDR_CHANGE: %s\n",str);
					break;
				case SCTP_REMOTE_ERROR:
					sre = &snp->sn_remote_error;
					printf("SCTP_REMOTE_ERROR\n");
					break;
				case SCTP_SEND_FAILED:
					ssf = &snp->sn_send_failed;
					printf("SCTP_SEND_FAILED\n");
					break;
#ifdef UN_MOD
				case SCTP_ADAPTATION_INDICATION:
					ae = &snp->sn_adaptation_event;
					printf("SCTP_ADAPTION_INDICATION\n");
					break;
#else
				case SCTP_ADAPTION_INDICATION:
					ae = &snp->sn_adaption_event;
					printf("SCTP_ADAPTION_INDICATION\n");
					break;
#endif
				case SCTP_PARTIAL_DELIVERY_EVENT:
					pdapi = &snp->sn_pdapi_event;
					if (pdapi->pdapi_indication == SCTP_PARTIAL_DELIVERY_ABORTED)
						printf("SCTP_PARTIAL_DELIEVERY_ABORTED\n");
					else
						printf("Unknown SCTP_PARTIAL_DELIVERY_EVENT\n");
					break;
				default:
					printf("UNKNOWN notification\n");
					break;
			}
			continue;
		}
		printf("%s",readbuf);
		ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
		if (ret_value == -1) {
			printf("sctp_sendmsg error\n");
			exit(-1);
		}

	}

	return 0;
}
Beispiel #2
0
static void* handle_connection(void *arg)
{
	ssize_t n;
	unsigned long long sum = 0;
	char *buf;
	pthread_t tid;
	int fd;
	struct timeval start_time, now, diff_time;
	double seconds;
	unsigned long messages = 0;
	unsigned long recv_calls = 0;
	unsigned long notifications = 0;
	unsigned int first_length;
	int flags;
	socklen_t len;

	fd = *(int *) arg;
	free(arg);
	tid = pthread_self();
	pthread_detach(tid);

	buf = malloc(BUFFERSIZE);
	flags = 0;
	len = (socklen_t)0;
	n = sctp_recvmsg(fd, (void*)buf, BUFFERSIZE, NULL, &len, NULL, &flags);
	gettimeofday(&start_time, NULL);
	first_length = 0;
	while (n > 0) {
		recv_calls++;
		if (flags & MSG_NOTIFICATION) {
			notifications++;
		} else {
			sum += n;
			if (flags & MSG_EOR) {
				messages++;
				if (first_length == 0)
					first_length = sum;
			}
		}
		flags = 0;
		len = (socklen_t)0;
		n = sctp_recvmsg(fd, (void*)buf, BUFFERSIZE, NULL, &len, NULL, &flags);
	}
	if (n < 0)
		perror("sctp_recvmsg");
	gettimeofday(&now, NULL);
	timersub(&now, &start_time, &diff_time);
	seconds = diff_time.tv_sec + (double)diff_time.tv_usec/1000000.0;
	fprintf(stdout, "%u, %lu, %lu, %lu, %llu, %f, %f\n",
	        first_length, messages, recv_calls, notifications, sum, seconds, (double)first_length * (double)messages / seconds);
	fflush(stdout);
	close(fd);
	free(buf);
	return NULL;
}
Beispiel #3
0
static void echo(int fd, int socketModeUDP)
{
   struct  sctp_sndrcvinfo  sri;
   char                     buf[BUFLEN];
   size_t                   buflen;
   ssize_t                  received;
   int                      flags;
   unsigned int             outgoing = 1;
   union sctp_notification *snp;

   /* Wait for something to echo */
   buflen = sizeof(buf);
   flags  = 0;
   received = sctp_recvmsg(fd, buf, buflen, NULL, 0, &sri, &flags);
   while(received > 0) {
      /* Intercept notifications here */
      if(flags & MSG_NOTIFICATION) {
         snp = (union sctp_notification *)buf;
         if(snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {
            /* incoming = snp->sn_assoc_change.sac_inbound_streams; */
            outgoing = snp->sn_assoc_change.sac_outbound_streams;
         }
         handle_event(buf);
      }
      else {
         printf("got %u bytes on stream %hu:\n", (unsigned int)received, sri.sinfo_stream);
         fflush(stdout);
         write(0, buf, received);

         /* Echo it back */
         if(sctp_sendmsg(fd, buf, received, NULL, 0,
                         0x29091976, 0,
                         sri.sinfo_stream % outgoing,
                         0, 0) < 0) {
            perror("sendmsg");
            exit(1);
         }
      }

      buflen = sizeof(buf);
      flags  = 0;
      received = sctp_recvmsg(fd, buf, buflen, NULL, 0, &sri, &flags);
   }

   if(received < 0) {
      perror("sctp_recvmsg");
   }
   if(socketModeUDP == 0) {
      ext_close(fd);
   }
}
Beispiel #4
0
ssize_t uwsgi_proto_sctp_read_body(struct wsgi_request * wsgi_req, char *buf, size_t len) {

	struct sctp_sndrcvinfo sinfo;
        memset(&sinfo, 0, sizeof(sinfo));
	int msg_flags = 0;
	struct uwsgi_header *uh;

	ssize_t slen = sctp_recvmsg(wsgi_req->socket->fd, buf, len, NULL, NULL, &sinfo, &msg_flags);

	if (slen <= 0) {
		return -1;
	}

	if (wsgi_req->stream_id != sinfo.sinfo_stream) {
		return -1;
	}

	uh = (struct uwsgi_header *) &sinfo.sinfo_ppid;

	if (uh->modifier1 != 199) {
		return -1;
	}

	return slen;
	
}
Beispiel #5
0
//==============================function implemen==============================
void sctpstr_cli(FILE *fp,int sock_fd,struct sockaddr *to,socklen_t tolen)
{
    struct sockaddr_in peeraddr;	// client的相關位址資料
    struct sctp_sndrcvinfo sri;	// send and recv端的資料
    char sendline[MAXLINE],recvline[MAXLINE];
    socklen_t len;
    int out_sz,rd_sz;
    int msg_flags;
    int ret_value=0;

    bzero(&sri,sizeof(sri));
    // block住,等待client端輸入
    while (fgets(sendline,MAXLINE,fp) != NULL) {
        if (sendline[0] != '[') {
            printf("Error, line must be of the form '[streamnum]text'\n");
            continue;
        }
        // string to long integer,表示sendline這一個字串是base在10進位去轉換
        // 透過設定的stream number來傳送資料
        sri.sinfo_stream = strtol(&sendline[1],NULL,0);
        out_sz = strlen(sendline);	// 輸入字串的長度,用來記錄等一下要傳送幾個字元
        ret_value = sctp_sendmsg(sock_fd,sendline,out_sz,to,tolen,0,0,sri.sinfo_stream,0,0);
        if (ret_value == -1) {
            printf("sctp_sendmsg error\n");
            exit(-1);
        }

        len = sizeof(peeraddr);
        rd_sz = sctp_recvmsg(sock_fd,recvline,sizeof(recvline),(struct sockaddr *) &peeraddr,&len,&sri,&msg_flags);
        printf("From str:%d seq:%d (assoc:0x%x):",sri.sinfo_stream,sri.sinfo_ssn,(u_int) sri.sinfo_assoc_id);
        printf("%.*s",rd_sz,recvline);
    }
}
Beispiel #6
0
void SctpSocket::OnRead()
{
/*
	int sctp_recvmsg(int sd, void * msg, size_t * len,
		struct sockaddr * from, socklen_t * fromlen,
		struct sctp_sndrcvinfo * sinfo, int * msg_flags);

	DESCRIPTION
	sctp_recvmsg  is  a  wrapper library function that can be used to receive a message from a socket while using the advanced
	features of SCTP.  sd is the socket descriptor on which the message pointed to by msg of length len is received.

	If from is not NULL, the source address of the message is filled in. The argument fromlen  is  a  value-result  parameter.
	initialized  to  the  size  of the buffer associated with from , and modified on return to indicate the actual size of the
	address stored.

	sinfo is a pointer to a sctp_sndrcvinfo structure to be filled upon receipt of the message.  msg_flags is a pointer  to  a
	integer that is filled with any message flags like MSG_NOTIFICATION or MSG_EOR.

*/
	struct sockaddr sa;
	socklen_t sa_len = 0;
	struct sctp_sndrcvinfo sinfo;
	int flags = 0;
	int n = sctp_recvmsg(GetSocket(), m_buf, SCTP_BUFSIZE_READ, &sa, &sa_len, &sinfo, &flags);
	if (n == -1)
	{
		Handler().LogError(this, "SctpSocket", Errno, StrError(Errno), LOG_LEVEL_FATAL);
		SetCloseAndDelete();
	}
	else
	{
		OnReceiveMessage(m_buf, n, &sa, sa_len, &sinfo, flags);
	}
}
Beispiel #7
0
void zmq::sctp_engine_t::in_event (handle_t handle_)
{
    //  Receive N messages in one go if possible - this way we'll avoid
    //  excessive polling.
    //  TODO: Move the constant to config.hpp
    int msg_nbr;
    for (msg_nbr = 0; msg_nbr != 1; msg_nbr ++) {

        unsigned char buffer [max_sctp_message_size]; 
        int msg_flags;
        ssize_t nbytes = sctp_recvmsg (s, buffer, sizeof (buffer),
            NULL, 0, NULL, &msg_flags);
        errno_assert (nbytes != -1);

        //  Create 0MQ message from the data.
        message_t msg (nbytes);
        memcpy (msg.data (), buffer, nbytes);

        //  TODO: Implement queue-full handling.
        bool ok = demux->write (msg);
        assert (ok);
    }

    //  Flash the messages to system, if there are any.
    if (msg_nbr > 0)
        demux->flush ();
}
// 有新的資料送過來
int SCTPClientSocket::recvMsg(int s)
{
    int ret;
    int msg_flags;
    char recvbuffer[1024];
    bzero(recvbuffer,1024);
    ret = sctp_recvmsg(s,recvbuffer,1024,(struct sockaddr *) NULL,0,(struct sctp_sndrcvinfo *) NULL, &msg_flags);
    if (ret == -1) {
        perror("sctp_recvmsg error");
        exit(-1);
    }
    else if (ret == 0) {
        delete sctp_notification;
        sctp_notification = NULL;
        close(s);
        emit serverclosed();
        qWarning("peer endpoint close the connection");
    }
    if (msg_flags & MSG_NOTIFICATION)
    {
        qWarning("there is some notification");
        SctpSocketHandler::emitSctpEvent(recvbuffer);
        return ret;
    }
    qWarning("recv %d bytes",ret);
    qWarning("%s",recvbuffer);

    return ret;
}
Beispiel #9
0
void SDStruct(int connfd)
{
	// 計算總共要傳送的檔案大小, 加8是表示兩個額外的int
	int totalsize = 3*(ready_image->height)*(ready_image->width)+8;
	printf("widthStep:%d\nheight:%d\nwidth:%d\ntotal:%d\n",ready_image->widthStep,ready_image->height,ready_image->width,totalsize);
	// begin記錄目前送到哪裡啦
	int begin=0;
	// 把一個檔案分成許多個檔案, 計算目前這一個要傳送多大的資料
	int ReadByte=0;
	int ret;
	char recvbuff[MAX_BUFFER];
	char *ptr = (char *)&matrix;
	do
	{
		if (totalsize>=begin+MAX_BUFFER)
		{
			ReadByte = MAX_BUFFER;
		}
		else
		{
			ReadByte = totalsize-begin;
		}
		if (ReadByte>0)
		{
			ret = sctp_sendmsg(connfd,ptr+begin,ReadByte,(struct sockaddr *) NULL,0,0,0,0,0,0);
			if (ret<=0)
			{
				printf("sctp_sendmsg error\n");
				return ;
			}
			else
			{
				// printf("send some data\n");
			}
			bzero(recvbuff,MAX_BUFFER);
			// 等待對方確實收到資料
			ret = sctp_recvmsg(connfd,recvbuff,MAX_BUFFER,(struct sockaddr *) NULL,(socklen_t *) NULL,NULL,NULL);
			if (ret <=0)
			{
				printf("sctp_recvmsg error\n");
				return ;
			}
			else
			{
				// printf("got some data\n");
				begin+=ReadByte;
			}
		}
		else
		{
			break;
		}
	}while(true);
	// 表示檔案已傳送結束
	ret = sctp_sendmsg(connfd,IMAGE_END,strlen(IMAGE_END),(struct sockaddr *) NULL,0,0,0,0,0,0);
	printf("\nClient imagedata Finish!!\n");
}
Beispiel #10
0
int proto_sctp_read(struct socket_info *si, int* bytes_read)
{
    struct receive_info ri;
    int len;
#ifdef DYN_BUF
    char* buf;
#else
    static char buf [BUF_SIZE+1];
#endif
    char *tmp;
    unsigned int fromlen;
    struct sctp_sndrcvinfo sinfo;

#ifdef DYN_BUF
    buf=pkg_malloc(BUF_SIZE+1);
    if (buf==0) {
        LM_ERR(" could not allocate receive buffer in pkg memory\n");
        goto error;
    }
#endif
    fromlen=sockaddru_len(si->su);
    len = sctp_recvmsg(si->socket, buf, BUF_SIZE, &ri.src_su.s, &fromlen,
                       &sinfo, 0);
    if (len==-1) {
        if (errno==EAGAIN) {
            LM_DBG("packet with bad checksum received\n");
            return 0;
        }
        if ((errno==EINTR)||(errno==EWOULDBLOCK)|| (errno==ECONNREFUSED))
            return -1;
        LM_ERR("sctp_recvmsg:[%d] %s\n", errno, strerror(errno));
        return -2;
    }

    /* we must 0-term the messages, receive_msg expects it */
    buf[len]=0; /* no need to save the previous char */

    ri.bind_address = si;
    ri.dst_port = si->port_no;
    ri.dst_ip = si->address;
    ri.proto = si->proto;
    ri.proto_reserved1 = ri.proto_reserved2 = 0;

    su2ip_addr(&ri.src_ip, &ri.src_su);
    ri.src_port=su_getport(&ri.src_su);

    if (ri.src_port==0) {
        tmp=ip_addr2a(&ri.src_ip);
        LM_INFO("dropping 0 port packet from %s\n", tmp);
        return 0;
    }

    /* receive_msg must free buf too!*/
    receive_msg(buf, len, &ri);

    return 0;
}
int main(int argc, char *argv[]) {
	int fd, n, flags;
	struct sockaddr_in addr;
	socklen_t from_len;
	struct sctp_sndrcvinfo sinfo;
	char buffer[BUFFER_SIZE];
	struct sctp_event_subscribe event;
      
	if ((fd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0) {
		perror("socket");
	}
	memset((void *)&event, 1, sizeof(struct sctp_event_subscribe));
	if (setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS,
		&event, sizeof(struct sctp_event_subscribe)) < 0) {
		perror("setsockopt");
	}
  
	memset((void *)&addr, 0, sizeof(struct sockaddr_in));
#ifdef HAVE_SIN_LEN
	addr.sin_len         = sizeof(struct sockaddr_in);
#endif
	addr.sin_family      = AF_INET;
	addr.sin_port        = htons(PORT);
	addr.sin_addr.s_addr = inet_addr(ADDR);
	if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
		perror("bind");
    	}
	if (listen(fd, 1) < 0) {
		perror("listen");
	}
	
	while (1) {
		flags = 0;
		memset((void *)&addr, 0, sizeof(struct sockaddr_in));
		from_len = (socklen_t)sizeof(struct sockaddr_in);
		memset((void *)&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
    
		n = sctp_recvmsg(fd, (void*)buffer, BUFFER_SIZE,
		                 (struct sockaddr *)&addr, &from_len,
	                         &sinfo, &flags);
                     
		if (flags & MSG_NOTIFICATION) {
			printf("Notification received.\n");
		} else {
			printf("Msg of length %d received from %s:%u on stream %d, PPID %d.\n",
			       n, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
			       sinfo.sinfo_stream, ntohl(sinfo.sinfo_ppid));
		}
	}
  
	if (close(fd) < 0) {
		perror("close");
	}
  
	return (0);
}
Beispiel #12
0
//=========================main function================================
int main(int argc, char **argv)
{
	int sock_fd,msg_flags;
	char readbuf[BUFFSIZE];
	struct sockaddr_in cliaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	socklen_t len;
	size_t rd_sz;
	struct sockaddr_in *paddr, a;
	unsigned char flag = 1;
	paddr = &a;
	paddr->sin_family = AF_INET;
	paddr->sin_port = htons(SERV_PORT);
	paddr->sin_addr.s_addr = INADDR_ANY;
	sock_fd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);

	if(fcntl(sock_fd,F_SETFL,O_NONBLOCK) <0)
	{
		printf("\r\n PID_UP::fcntl:O_NONBLOCK error\n ");
		return -1;
	}

	if (-1 == bind(sock_fd, (struct sockaddr*)paddr, sizeof(struct sockaddr))) {
		printf( "ERRNO:%d\n ", errno);
		perror( "E_bind_Fail ");
		return -1;
	}
	bzero(&evnts, sizeof(evnts)); 
	evnts.sctp_data_io_event = 1; 
	/* end mod_serv07 */ 
	evnts.sctp_association_event = 1; 
	evnts.sctp_address_event = 1; 
	evnts.sctp_send_failure_event = 1; 
	evnts.sctp_peer_error_event = 1; 
	evnts.sctp_shutdown_event = 1; 
	evnts.sctp_partial_delivery_event = 1; 
	evnts.sctp_adaptation_layer_event = 1; 
	setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)); 

	listen(sock_fd, 10); 
	printf("listen.............\n");
	for ( ; ; ) {
		len = sizeof(struct sockaddr_in);
		// print_time_info();
		rd_sz = sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),(struct sockaddr *)&cliaddr, &len,&sri,&msg_flags);
		if(msg_flags & MSG_NOTIFICATION) {
			printf( "msg_flags (%d),MSG_NOTIFICATION(%d)\n ",msg_flags,MSG_NOTIFICATION);
			print_notification(readbuf);
			continue;
		}
		sctp_sendmsg(sock_fd, readbuf, rd_sz,(struct sockaddr *)&cliaddr, len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0, 0);
	}
}
Beispiel #13
0
int Sctp_recvmsg(int s, void* msg, size_t len, struct sockaddr* from,
                 socklen_t* fromlen, struct sctp_sndrcvinfo* sinfo,
                 int* msg_flags)
{
    int ret;
    ret = sctp_recvmsg(s, msg, len, from, fromlen, sinfo, msg_flags);
    if (ret < 0) {
        err_sys("sctp_recvmsg error");
    }
    return (ret);
}
Beispiel #14
0
void message::printsys()
{
	len = sizeof(struct sockaddr_in);
	rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);
	ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
	if (ret_value == -1)
	{
		qWarning("sctp_sendmsg error");
		exit(-1);
	}
}
Beispiel #15
0
int
main(int argc, char **argv)
{
	int sock_fd,msg_flags;
	char readbuf[BUFFSIZE];
	struct sockaddr_in6 servaddr, cliaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	int stream_increment=1;
	socklen_t len;
	size_t rd_sz;

	if (argc == 2)
		stream_increment = atoi(argv[1]);
        sock_fd = socket(AF_INET6, SOCK_SEQPACKET, IPPROTO_SCTP);
	if (sock_fd < 0)
  	{
    		perror("socket()");
    		exit(errno);
  	}

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin6_family = AF_INET;
//	servaddr.sin6_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin6_port = htons(SERV_PORT);

	bind(sock_fd, (SA *) &servaddr, sizeof(servaddr));
	
	bzero(&evnts, sizeof(evnts));
	evnts.sctp_data_io_event = 1;
	setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS,
		   &evnts, sizeof(evnts));

	listen(sock_fd, LISTENQ);
	for ( ; ; ) {
		len = sizeof(struct sockaddr_in6);
		rd_sz = sctp_recvmsg(sock_fd, readbuf, sizeof(readbuf),
			     (SA *)&cliaddr, &len,
			     &sri,&msg_flags);
		if(stream_increment) {
			sri.sinfo_stream++;
			if(sri.sinfo_stream >= sctp_get_no_strms(sock_fd,(SA *)&cliaddr, len)) 
				sri.sinfo_stream = 0;
		}
		sctp_sendmsg(sock_fd, readbuf, rd_sz, 
			     (SA *)&cliaddr, len,
			     sri.sinfo_ppid,
			     sri.sinfo_flags,
			     sri.sinfo_stream,
			     0, 0);
	}
}
/* Used only with one-to-one socket.
 *
 * Event callback when there is data available on the registered 
 * socket to recv.
 */
static void mca_btl_sctp_component_recv_handler(int sd, short flags, void* user)
{
    orte_process_name_t guid;
    struct sockaddr_in addr;
    int retval;
    mca_btl_sctp_proc_t* btl_proc;
    opal_socklen_t addr_len = sizeof(addr);
    mca_btl_sctp_event_t *event = (mca_btl_sctp_event_t *)user;
    int msg_flags=0;
    struct sctp_sndrcvinfo sri;
    
    /* accept new connections on the listen socket */
    if(mca_btl_sctp_component.sctp_listen_sd == sd) {
        mca_btl_sctp_component_accept();
        return;
    }
    OBJ_RELEASE(event);

    retval = sctp_recvmsg(sd, (char *)&guid, sizeof(guid), 0, 0, &sri, &msg_flags);

    if(retval != sizeof(guid)) {
        CLOSE_THE_SOCKET(sd); 
        return; 
    }
    SCTP_BTL_ERROR(("mca_btl_sctp_component_recv_handler() sd=%d, got %d byte guid.\n", sd, retval));

    ORTE_PROCESS_NAME_NTOH(guid);
   
    /* lookup the corresponding process */
    btl_proc = mca_btl_sctp_proc_lookup(&guid);
    if(NULL == btl_proc) {
        BTL_ERROR(("errno=%d",errno));
        CLOSE_THE_SOCKET(sd);
        return;
    }

    /* lookup peer address */
    if(getpeername(sd, (struct sockaddr*)&addr, &addr_len) != 0) {
        if(opal_socket_errno != ECONNRESET && opal_socket_errno != EBADF && opal_socket_errno != ENOTCONN) {
            BTL_ERROR(("getpeername() failed with errno=%d", opal_socket_errno));
        }
        CLOSE_THE_SOCKET(sd);
        return;
    }

    /* are there any existing peer instances will to accept this connection */
    if(mca_btl_sctp_proc_accept(btl_proc, &addr, sd) == false) {
        CLOSE_THE_SOCKET(sd);
        return;
    }
}
Beispiel #17
0
int uwsgi_proto_sctp_parser(struct wsgi_request *wsgi_req) {

	struct sctp_sndrcvinfo sinfo;
	memset(&sinfo, 0, sizeof(sinfo));
	int msg_flags = 0;

	ssize_t len = sctp_recvmsg(wsgi_req->socket->fd, wsgi_req->buffer, uwsgi.buffer_size, NULL, NULL, &sinfo, &msg_flags);

	if (len <= 0) {
		if (len < 0)
			uwsgi_error("sctp_recvmsg()");
		uwsgi_log("lost connection with the SCTP server %d\n", msg_flags);
		// connection lost, retrigger it
		close(wsgi_req->socket->fd);
		wsgi_req->socket->fd = connect_to_sctp(wsgi_req->socket->name, wsgi_req->socket->queue);
		// avoid closing connection
		wsgi_req->fd_closed = 1;
		// no special message needed
		return -3;
	}

	// get the uwsgi 4 bytes header from ppid
	memcpy(&wsgi_req->uh, &sinfo.sinfo_ppid, sizeof(uint32_t));

	// check for invalid modifiers
	if (wsgi_req->uh.modifier1 == 199 || wsgi_req->uh.modifier1 == 200) {
		uwsgi_log("invalid SCTP uwsgi modifier1: %d\n", wsgi_req->uh.modifier1);
		return -1;
	}

	wsgi_req->stream_id = sinfo.sinfo_stream;
	
/* big endian ? */
#ifdef __BIG_ENDIAN__
	wsgi_req->uh.pktsize = uwsgi_swap16(wsgi_req->uh.pktsize);
#endif

#ifdef UWSGI_DEBUG
	uwsgi_debug("uwsgi payload size: %d (0x%X) modifier1: %d modifier2: %d\n", wsgi_req->uh.pktsize, wsgi_req->uh.pktsize, wsgi_req->uh.modifier1, wsgi_req->uh.modifier2);
#endif

	/* check for max buffer size */
	if (wsgi_req->uh.pktsize > uwsgi.buffer_size) {
		uwsgi_log("invalid request block size: %d (max %d)...skip\n", wsgi_req->uh.pktsize, uwsgi.buffer_size);
		return -1;
	}

	return UWSGI_OK;

}
Beispiel #18
0
int Sock_read(Sock *s, void *buffer, int nbytes, void *protodata, int flags)
{

    socklen_t sa_len = sizeof(struct sockaddr_storage);

    if(!s)
        return -1;

#if ENABLE_SSL
    if (s->ssl)
        SSL_sock_read(s->ssl, buffer, nbytes);
    else {
#endif
        switch(s->socktype) {
        case UDP:
            if (!protodata) {
                protodata = &s->remote_stg;
            }
            return recvfrom(s->fd, buffer, nbytes, flags,
                (struct sockaddr *) protodata, &sa_len);
            break;
        case TCP:
            return recv(s->fd, buffer, nbytes, flags);
            break;
        case SCTP:
#ifdef HAVE_SCTP
            if (!protodata) {
                return -1;
            }
            return sctp_recvmsg(s->fd, buffer, nbytes, NULL,
                 0, (struct sctp_sndrcvinfo *) protodata, &flags);
            /* flags is discarted: usage may include detection of
             * incomplete packet due to small buffer or detection of
             * notification data (this last should be probably
             * handled inside netembryo).
             */
#endif
            break;
        case LOCAL:
            return recv(s->fd, buffer, nbytes, flags);
            break;
        default:
            break;
        }
#if ENABLE_SSL
    }
#endif

    return -1;
}
main()
{
	int sd;
	int e,f=0;
	char buffer[1000];

	sd = socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
	if(sd == -1) {
		printf("socket failed %d\n", errno);
	}
	listen(sd, 2);
	e = sctp_recvmsg(sd, buffer, sizeof(buffer),
			 (NULL), 0, NULL, &f);
	printf("Returned %d errno:%d\n", e, errno);
}
Beispiel #20
0
main(int argc, char* argv[])
{
   int   sd;
   struct   sockaddr_in server;
   char buf[512];
   int rc;
   int msg_flags;
   struct sockaddr_in cliaddr;
   int len;
   struct sctp_sndrcvinfo sri;
   struct sctp_event_subscribe evnts;
   int stream_increment=1;
   struct sctp_initmsg initm;


   server.sin_family = AF_INET;
   server.sin_addr.s_addr = htonl(INADDR_ANY);
   server.sin_port = htons(atoi(argv[1]));

   sd = socket (AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
   reusePort(sd);

   if (   bind( sd, (SA *) &server, sizeof(server) ) < 0 ){
      printf("error binding\n");
      exit(-1) ;
   }

   listen(sd, 1);

   for(;;){
      len = sizeof(struct sockaddr_in);
      rc = sctp_recvmsg(sd, buf, sizeof(buf), (SA *)&cliaddr, &len, &sri, &msg_flags);
      buf[rc]= (char) NULL;
      printf("sctp_recvmsg: %s\n", buf);

      rc = recvfrom (sd, buf, sizeof(buf), 0, (SA *) &cliaddr, &len);
      buf[rc]= (char) NULL;
      printf("recvfrom: %s\n", buf);

      len = sizeof(cliaddr);
      getpeername(sd, (SA *) &cliaddr, &len);
      printf("remote addr: %s,  port %d\n",
          inet_ntop(AF_INET, &cliaddr.sin_addr, buf,
          sizeof(buf)), ntohs(cliaddr.sin_port));

   }
}
static gssize
sctp_socket_receive_with_blocking (GSocket * socket, gchar * buffer, gsize size,
    gboolean blocking, GCancellable * cancellable, guint * streamid,
    GError ** error)
{
  gssize ret;

  if (g_socket_is_closed (socket)) {
    g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
        "Socket is already closed");
    return -1;
  }

  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    return -1;

  while (TRUE) {
    struct sctp_sndrcvinfo sndrcvinfo;
    int flags = 0;

    if (blocking &&
        !g_socket_condition_wait (socket, G_IO_IN, cancellable, error))
      return -1;

    if ((ret = sctp_recvmsg (g_socket_get_fd (socket), buffer, size, NULL, 0,
                &sndrcvinfo, &flags)) < 0) {
      if (errno == EINTR)
        continue;

      if (blocking) {
        if (errno == EWOULDBLOCK || errno == EAGAIN)
          continue;
      }

      g_set_error (error, G_IO_ERROR, errno, "Error receiving data: %s",
          strerror (errno));

      return -1;
    }

    *streamid = sndrcvinfo.sinfo_stream;
    break;
  }

  return ret;
}
int main(int argc,char **argv)
{
	int sock_fd,msg_flags;
	char readbuf[1024];
	struct sockaddr_in servaddr,cliaddr;
	struct sctp_sndrcvinfo sri;
	struct sctp_event_subscribe evnts;
	socklen_t len;
	size_t rd_sz;

	if ((sock_fd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP)) < 0) {
		perror("socket");
	}

	bzero(&servaddr,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(9877);
	if (bind(sock_fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
		perror("bind");
	}

	bzero(&evnts, sizeof(evnts));
	evnts.sctp_data_io_event = 1;
	if (setsockopt(sock_fd,IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) < 0) {
		perror("setsockopt");
	}

	if (listen(sock_fd,5) < 0) {
		perror("listen");
	}

	for (;;) {
		len = sizeof(struct sockaddr_in);
		printf("start wait...\n");
		rd_sz = sctp_recvmsg(sock_fd,readbuf, sizeof(readbuf), (struct sockaddr *)&cliaddr, &len, &sri, &msg_flags);
		printf("sctp_recvmsg() received %d bytes from %s:%d.\n", (int)rd_sz, inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
		if (rd_sz > 0) {
			if (sctp_sendmsg(sock_fd, readbuf, rd_sz, (struct sockaddr *)&cliaddr, len, sri.sinfo_ppid, sri.sinfo_flags, sri.sinfo_stream, 0, 0) < 0) {
				perror("sctp_sendmsg");
			}
		}
	}
	return 0;
}
Beispiel #23
0
/***************************************************************************
** read message from socket and pass it to M3UA
****************************************************************************/
int	get_message(int		fid,
                    int		sockid,
                    unsigned char  msg[1024],
                    unsigned int   *pmsglen)
{
    iu_log_debug("%s  %d: %s\n",__FILE__, __LINE__, __func__);
    int			idx;
    int			tid;
    struct sockaddr_in	addr;	
    unsigned int		len = sizeof(struct sockaddr);
	int			msg_flags;
	struct sctp_sndrcvinfo sri;

	len = sizeof (struct sockaddr_in);
    memset(&addr, 0, sizeof(struct sockaddr));
	*pmsglen = sctp_recvmsg (sockid, msg, 1024,
					(struct sockaddr *)&addr, &len, &sri, &msg_flags);
	if (*pmsglen <= 0) {
		iu_log_debug("E_sctp_recvmsg_Fail \n");
		return 0;
	}
	if (msg_flags & MSG_NOTIFICATION) {
		iu_log_debug("MSG_NOTIFICATION, msg_flags=%X \n", msg_flags);
		return 0;
	}

    if (0 < *pmsglen) {
        /* search for association for which data is received */
        for (idx = 0; idx < MAX_REMOTE_EP; idx++) {
            if (1 == assoc_table[fid*MAX_REMOTE_EP + idx].e_state) {
                tid = assoc_table[fid*MAX_REMOTE_EP + idx].to;
                iu_log_debug("addr.sin_family = %d\n",addr.sin_family);
                iu_log_debug("addr.sin_port = %d\n",addr.sin_port);
                iu_log_debug("addr.sin_addr.s_addr = %d\n",addr.sin_addr.s_addr);
                
                m3ua_recvmsg((fid*MAX_REMOTE_EP + idx), 0, *pmsglen, msg);
            }
        }
    }
    return 0;
}
Beispiel #24
0
int recv_from_target(int sk, 
                                        void *msg,
                                        size_t len,
                                        struct sockaddr *from,
                                        socklen_t *fromlen,
                                        struct sctp_sndrcvinfo *sinfo,
                                        int *msg_flags)
{
	int recv_len = -1;
	do 
	{
        recv_len = sctp_recvmsg(sk, msg, len, from, fromlen, sinfo, msg_flags);
        if (-1 == recv_len)
        {
            perror("sctp_recvmsg");
            break;
        }
	} while (0);

	return recv_len;	
}
Beispiel #25
0
int main()
{
  int connSock, in, i, ret, flags;
  struct sockaddr_in servaddr;
  struct sctp_status status;
  char buffer[MAX_BUFFER+1];

  connSock = socket( AF_INET, SOCK_STREAM, IPPROTO_SCTP );

  if(connSock == -1)
    die("socket()");

  bzero( (void *)&servaddr, sizeof(servaddr) );
  servaddr.sin_family = AF_INET;
  servaddr.sin_port = htons(MY_PORT_NUM);
  // servaddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
  servaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

  ret = connect( connSock, (struct sockaddr *)&servaddr, sizeof(servaddr) );
  
  if(ret == -1)
    die("connect()");

  printf("Enter data to send : ");
  gets(buffer);
  // scanf("%s", buffer);
  //getchar();
  
  ret = sctp_sendmsg( connSock, (void *)buffer, (size_t)strlen(buffer), NULL, 0, 0, 0, 0, 0, 0 );
  memset(buffer, '\0', sizeof(buffer));
  // printf("ret = %d\n", ret);
  in = sctp_recvmsg( connSock, (void *)buffer, sizeof(buffer), (struct sockaddr *)NULL, 0, 0, 0 );
  // printf("in = %d\n", in);
  printf("response = %s\n", buffer);
  memset(buffer, '\0', sizeof(buffer));

  close(connSock);

  return 0;
}
Beispiel #26
0
/** 
 * @brief Wait for incoming data and read it if it becomes available. 
 *
 * If the peer is non-null, then it is assumed that the socket is in
 * SEQPKT state.
 * 
 * @param sock Socket to use
 * @param timeout_ms Number of milliseconds to wait for incoming data.
 * @param chunk Pointer to the buffer where received data is read.
 * @param chunk_len Maximum number of bytes to read.
 * @param peer  Sockaddr where the peers address is to be set.
 * @param peerlen Size of the address structure.
 * @param info  Pointer for the structure where the additional SCTP information is to be saved.
 * @param flags Pointer where the receiving flags should be written.
 * 
 * @return  Number of bytes read on success, 0 on timeout and -1 on error, -2 if the 
 * remote end has shut down.
 */
int recv_wait( int sock, time_t timeout_ms, uint8_t *chunk, size_t chunk_len,
                struct sockaddr *peer, socklen_t *peerlen,
                struct sctp_sndrcvinfo *info, int *flags )
{
        fd_set fds;
        struct timeval tv;
        int ret;

        FD_ZERO( &fds );
        FD_SET( sock, &fds );
        memset( &tv, 0, sizeof( tv ));

        tv.tv_usec = timeout_ms * 1000;

        ret = select( sock+1, &fds, NULL, NULL, &tv );
        if ( ret < 0 ) {
                WARN("Error in select() : %s \n", strerror( errno ));
                return -1;
        } else if ( ret > 0 ) {
                if ( ! FD_ISSET( sock, &fds ) ) 
                        return -1; /* should not happen */

                ret = sctp_recvmsg( sock, chunk, chunk_len, 
                                peer, peerlen, info, flags );

                TRACE("Received %d bytes of chunk (size %d ) \n", ret, chunk_len );
                if ( ret < 0 ) {
                        if ( errno == ECONNRESET ) 
                                ret = -2;
                        else
                                ret = -1;
                } else if ( ret == 0 ){
                        ret = -2;
                }

        }

        return ret;
}
Beispiel #27
0
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;
    int ret_value=0;

    // the client initializes the sri structure used to set up the stream it will be sending and receiving from
    bzero(sendline,sizeof(sendline));
    bzero(&sri,sizeof(sri));
    while(fgets(sendline,SCTP_MAXLINE-9,fp) != NULL) {
        strsz = strlen(sendline);
        // delete the newline character that is at the end of the buffer
        if (sendline[strsz-1] == '\n') {
            sendline[strsz-1]='\0';
            strsz--;
        }
        // 傳送SERV_MAX_SCTP_STRM筆資料給server
        for (i=0; i<SERV_MAX_SCTP_STRM; i++) {
            snprintf(sendline+strsz,sizeof(sendline)-strsz,".msg.%d",i);
            ret_value = sctp_sendmsg(sock_fd,sendline,sizeof(sendline),to,tolen,0,0,i,0,0);
            if (ret_value == -1) {
                printf("sctp_sendmsg error\n");
                exit(-1);
            }
        }
        // 由server接收SERV_MAX_SCTP_STRM筆資料
        for (i=0; i<SERV_MAX_SCTP_STRM; i++) {
            len = sizeof(peeraddr);
            rd_sz = sctp_recvmsg(sock_fd,recvline,sizeof(recvline),(struct sockaddr *) &peeraddr,&len,&sri,&msg_flags);
            printf("From str:%d seq:%d (assoc:0x%x):",sri.sinfo_stream,sri.sinfo_ssn,(u_int) sri.sinfo_assoc_id);
            printf("%.*s\n",rd_sz,recvline);
        }
    }
}
//Transport Layer Wrappers
int nmst_read(nms_transport * transport, void *buffer, size_t nbytes, void *protodata)
{
	int cnt = 0;
	int read_size = 0;
        switch (transport->sock.socktype) {
        case TCP:
		  while((read_size = read(transport->sock.fd, buffer, nbytes)) <= 0 && cnt++ <5) usleep(1) ;
                return read_size;
                break;
#ifdef HAVE_LIBSCTP
        case SCTP:
                if (!protodata) {
                        return -1;
                }
                return sctp_recvmsg(transport->sock.fd, buffer, nbytes, NULL, 0,
                                    (struct sctp_sndrcvinfo *) protodata, NULL);
                break;
#endif
        default:
                break;
        }
        return -1;
}
Beispiel #29
0
void recvdata() {
	int flag;
	struct sctp_sndrcvinfo recvinfo;
	char buf[10];
	sctp_recvmsg(csock, buf, sizeof(buf), NULL, 0, &recvinfo, &flag);
}
Beispiel #30
0
int main(int argc,char **argv)
{
	int listenSock, connSock, flags;
	int ret;
	struct sockaddr_in serv_addr,cli_addr;
	socklen_t server_len,client_len;
	struct sctp_sndrcvinfo sndrcvinfo;
	char buffer[MAX_BUFFER];
	client_len = sizeof(cli_addr);

	// 輸入要縮放的大小
	printf("please input a scale value (0<scale_value<1):");
	scanf("%f",&scale_value);

	// 建立一個one-to-one style的sctp socket
	listenSock = ::socket(AF_INET,SOCK_STREAM,IPPROTO_SCTP);

	if (listenSock == -1) {
		perror("ERROR opening socket");
		exit(1);
	}

	// 使得可以短時間內再度啟動程式(使用的port是相同的)
	int on=1;
	if (setsockopt(listenSock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==-1) {
		perror("set SO_RESUEADDR ERROR");
	}

	printf("connSock : %d\n",listenSock);

	bzero(&serv_addr,sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(MY_PORT_NUM);

	// bind - bind a name to a socket
	if ((::bind(listenSock,(struct sockaddr *) &serv_addr, sizeof(serv_addr)))==-1) {
		perror("listen error");
		exit(1);
	}

	if (::listen(listenSock,5)==-1) {
		perror("listen error");
		exit(1);
	}

	printf("Accepting connections ...\n");
	while(1)
	{	client_len = sizeof(cli_addr);
		connSock = ::accept(listenSock,(struct sockaddr *) &cli_addr,&client_len);
		if (connSock == -1) {
			perror("accept error");
			exit(1);
		}
		else
		{
			int flag = 1;
			// 一有資料馬上就送出去
			ret = ::setsockopt(connSock,IPPROTO_SCTP,SCTP_NODELAY,&flag,sizeof(flag));
			if (ret == -1) {
				perror("setsockopt SCTP_NODELAY error");
			}
			printf("accept the client connect...\n");
		}
		// 等待client傳送指令過來
		do {
			bzero(buffer,sizeof(buffer));
			ret = sctp_recvmsg(connSock,buffer,sizeof(buffer),(struct sockaddr *) NULL,(socklen_t *) NULL,&sndrcvinfo,&flags);
			analyze(buffer,connSock);
		}while(ret != -1 && ret != 0);

		switch (ret)
		{
			case 0:
				printf("the client close the connection\n");
				::close(connSock);
				break;
			case -1:
				printf("the connection has some error\n");
				::close(connSock);
				break;
			default:
				printf("It is impossible!\n");
		}
	}
	::close(listenSock);
	return 0;
}