⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ts2udp.c

📁 ftam等标准协议服务器和客户端的源代码。
💻 C
📖 第 1 页 / 共 2 页
字号:
int	fd,	newfd;struct sockaddr_in *sock;{    int	    nfds,	    sd;    fd_set  ifds;    register struct qbuf *qb;    register struct udpconn *up;    if (fd < 0 || fd >= maxpeers || peers[fd].udp_parent != fd) {	errno = EINVAL;	return NOTOK;    }    if (newfd) {	FD_ZERO (&ifds);	nfds = fd + 1;	FD_SET (fd, &ifds);	if (udp_select_socket (nfds, &ifds, NULLFD, NULLFD, OK) == NOTOK)	    return NOTOK;	up = &peers[fd];	if ((qb = up -> udp_queue.qb_forw) == &up -> udp_queue) {	    errno = EWOULDBLOCK;	    return NOTOK;	}	if ((sd = dup (fd)) == NOTOK)	    return NOTOK;	up = &peers[sd];	*sock = *((struct sockaddr_in *) qb -> qb_base);    /* struct copy */	remque (qb);	insque (qb, up -> udp_queue.qb_back);    }    else	up = &peers[sd = fd];    up -> udp_parent = fd;    bcopy ((char *) sock, (char *) &up -> udp_peer, sizeof up -> udp_peer);    return (newfd ? sd : OK);}#endif  /* if FALSE *//*  *//*  ********************************************************** *                                                        * *  udp read socket                                       * *                                                        * *  This routine reads datagram messages on the DATAGRAM  * *  socket running over UDP/IP.  The data is read into a  * *  buffer and queued on the qbuf struct passed on input. * *                                                        * *  returns:  # of bytes read                             * *                                                        * ********************************************************** */ int	udp_read_socket (fd, q, secs, fromsock, td)int	    	fd;struct qbuf 	*q;int	    	secs;struct sockaddr_in 	*fromsock;struct TSAPdisconnect   *td;{    int		cc;    int	    	nfds;    fd_set  	ifds,	     	mask;    struct qbuf qbuff;    register struct qbuf 	*qb = &qbuff;    register struct udpconn 	*up;    struct sockaddr_in 		*sock;    char 			*rbufptr;    int 			i;#ifdef HULADEBUG    		printf ("\n          in udp read socket \n");#endif/* *  Check for valid socket descriptor and set the udpconn struct ptr. */    if (fd < 0 ||        fd >= maxpeers ||        (up = &peers[fd]) -> udp_parent == NOTOK)            {	    errno = EINVAL;	    return tusaplose (td, DR_PARAMETER, NULLCP, TuErrString(UDERR_INVALID_XPORT_DESC));	                }/* *  Set up the file descriptor mask for the select. *  Select will tell if the socket is readable if we set the  *  read mask. *//*  *  Make sure the queue is empty before reading more data. */    if ((qb = up -> udp_queue.qb_forw) == &up -> udp_queue)        {	FD_ZERO (&ifds);/*   *  	Set the number of file descriptors we want to check.  Select *  	examines the I/O descriptors in the bits 0 thru (nfds - 1) *  	so add 1 to get the file descriptor we want. */	nfds = fd + 1;	FD_SET (fd, &mask);/* *      Select the socket to determine if there is data that *	can be read.  The call to udp_select_socket not only *      selects the socket but also dequeues any data onto the  *      read queue contained in the udpconn structure for the  *      active socket. */	for (ifds = mask ; ; ifds = mask)            {	    if (udp_select_socket (nfds,	/* # of fd's     */				   &ifds,	/* & read mask   */				   NULLFD,      /* & write mask  */				   NULLFD,      /* & excptn mask */				   secs)	/* seconds wait   */ 		    == NOTOK)		return tusaplose (td, DR_OPERATION, NULLCP, NULLCP);            	    /* 	     *  Check if we dequeued any data.             */	    if ((qb = up -> udp_queue.qb_forw) != &up -> udp_queue)		break;	    return tusaplose (td, DR_TIMER, NULLCP, NULLCP);	    	    }        }/*  *  Remove the queue buffer from its queue and return it. */#ifdef HULADEBUG    		printf ("\n          Removing the queued data from select\n");#endif    remque (qb);    /*     *  Format the qbuf with the real data info.     */    q -> qb_len = qb -> qb_len;    q -> qb_data = qb -> qb_data;    q -> qb_base[0] = qb -> qb_base[0];	#ifdef HULADEBUG	printf ("\n qb_data = \n");	for (cc=0; cc<25; cc++)	    printf (" %x ", *((qb -> qb_data) + cc) );	printf ("\n q_data = \n");	for (cc=0; cc<25; cc++)	    printf (" %x ", *((q -> qb_data) + cc) );#endif   /*      *  Copy the fromsocket address saved in the udp peers array.    */    bcopy ((char *) &up -> udp_peer, (char *) fromsock, sizeof up -> udp_peer);    return qb -> qb_len;}/*  *//*  ********************************************************** *                                                        * *  udp write socket                                      * *                                                        * *  This routine writes datagram messages on the DATAGRAM * *  socket running over UDP/IP.  The data is written from * *  the qbuf buffer using the EXCELAN socket library call * *  'send'.                                               * *                                                        * *  returns:  # of bytes written                          * *                                                        * ********************************************************** */int	udp_write_socket (fd, data, cc, td)int	fd;register char *data;int	cc;struct TSAPdisconnect *td;{    register struct udpconn *up;int	len;/*   *  Check for valid socket descriptor and set the  *  udpconn struct ptr for the socket. */    if (fd < 0 ||        fd >= maxpeers ||	(up = &peers[fd]) -> udp_parent == NOTOK#if FALSE ||	up -> udp_peer.sin_family == 0)#endif      )	    {	    errno = EINVAL;	    return NOTOK;            }/* *  Issue the write to the socket.  It returns the number *  of bytes written. */#ifdef HULADEBUG    printf ("\n          send datagram: ");    printf (" socket = %d  len = %d  \n", fd, cc);#endif        errno = 0;    return send (fd,			/* sd       */		 NULL,		        /* to addr  */		 data,			/* buffer   */		 cc);			/* buf size */		}/*  */int	udp_close (fd)int	fd;{    register struct qbuf *qb,			 *qp;    register struct udpconn *up,			    *vp;#ifdef HULADEBUG    printf ("\n          close socket: %d", fd);#endif    #if FALSE    if (fd < 0 || fd >= maxpeers || (up = &peers[fd]) -> udp_parent == NOTOK) {	errno = EINVAL;	return NOTOK;    }    up -> udp_parent = NOTOK;    bzero ((char *) &up -> udp_peer, sizeof up -> udp_peer);    for (qb = up -> udp_queue.qb_forw; qb != &up -> udp_queue; qb = qp) {	qp = qb -> qb_forw;	remque (qb);	free ((char *) qb);    }        for (vp = (up = peers) + maxpeers; up < vp; up++)	if (up -> udp_parent == fd)	    up -> udp_parent = up - peers;#endif    return close (fd);}/*  *//*  ********************************************************** *                                                        * *  udp select socket                                     * *                                                        * *  This routine handles doing the select to enable       * *  reading data on the socket.                           * *                                                        * *  If data is readable on the socket, this routine will  * *  also do the actual read on the socket and queue the   * *  data on the udpconn struct read queue.                * * 							  * *  synchronous multiplexing:				  * *							  * *      secs < 0:  block indefinitely			  * *      secs = 0:  poll					  * *      secs > 0:  wait for secs (in milliseconds)        * *                                                        * *  returns:  OK, NOTOK                                   * *                                                        * ********************************************************** */int	udp_select_socket (nfds, rfds, wfds, efds, secs)int	nfds;fd_set *rfds,       *wfds,       *efds;int	secs;{    register int    fd;    int	    cc,	    len,	    mfds,	    result;    fd_set  ifds,	    jfds;    register struct qbuf *qb;    register struct udpconn *up,			    *vp;    struct udpconn *wp;    struct sockaddr_in *sock;    char   *recvptr;#ifdef HULADEBUG    		printf ("\n          in udp select socket \n");#endif/*   *  Check if the read mask is set.  Then check if any read masks *  are set on each socket descriptor in the udpconn array. */    if (rfds)         {	jfds = *rfds;	if (secs != OK)#ifdef HULADEBUG            printf ("\n          checking the read masks of all peers \n");#endif	    for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++)		if (up -> udp_parent != NOTOK &&		    FD_ISSET (fd, &jfds) &&		    up -> udp_queue.qb_forw != &up -> udp_queue)    	                {			/*			 *  We found data pending on this socket.			 */		        secs = OK;		        break;		        }        }  /* end if rfds *//* *  Now do the real select to enable reading the socket. *  The 'selsocket' routine is a front end routine that *  implements the semantics of the Berkley select. */#ifdef HULADEBUG    		printf ("\n          doing the select on the read mask \n");#endif    if ((result = selsocket (nfds, rfds, wfds, efds, secs)) == NOTOK	    || rfds == NULLFD)	return result;#ifdef HULADEBUG    		printf ("\n          return from select # = %d\n", result);#endif    ifds = *rfds;/* *  Read the datagrams on each socket descriptor in the udpconn *  array that has its read enable bit set.  Each datagram message *  is put on the respective read queue for the socket. */     if ((mfds = nfds) > maxpeers)	mfds = maxpeers;/* *  Cycle thru each socket in the peers array. */    for (fd = 0, up = peers; fd < mfds; fd++, up++)	if (FD_ISSET (fd, &ifds))	    {	    if (up -> udp_parent == NOTOK)		continue;/* *          Allocate a qbuf structure and socket structure and  *          data buffer for the max datagram size (8K over EXCELAN). *          These are all allocated contiguously. */	    if ( (qb = (struct qbuf *) malloc (sizeof *qb + sizeof *sock) )		   == NULL)		return NOTOK;	    if ( (recvptr = (char *) malloc (8*1024) ) == NULL)		{		free ((char *) qb);		return NOTOK;		}/* *          Setup the socket and qbuf structures. */	    sock = (struct sockaddr_in *) qb -> qb_base;	    len = sizeof *sock;	    qb -> qb_data = recvptr;/* * 	    Do the DATAGRAM read on the socket to dequeue the *          data into the qbuf data buffer. */#ifdef HULADEBUG    		printf ("\n          datagram receive on sock %d \n", fd);#endif	    errno = 0;	    if (( cc = receive  (				fd,			  /* sd        */				sock, 			  /* from addr */			 	qb -> qb_data,	  	  /* buffer    */				(8*1024)   	  	  /* buf size  */  				)) == NOTOK)		{		free ((char *) qb); 		return NOTOK;    	        }/* *          Update the actual count of the bytes read. */#ifdef HULADEBUG    	    printf ("\n          received datagram - %d bytes long \n", cc);	printf ("\n data = \n");	for (len=0; len<25; len++)	    printf (" %x ", *((qb -> qb_data) + len) );#endif	    qb -> qb_len = cc;/*       *          Save the remote socket address in the udpconn struct *	    and put the data on its queue. */   	    bcopy ( (char *) sock, (char *) &up -> udp_peer, sizeof *sock);#ifdef HULADEBUG    		printf ("\n          queueing data on the active socket\n");#endif   	    insque (qb, up -> udp_queue.qb_back);	    continue;/* *	    If not for the current udpconn struct, then search the  *          peers array for the matching socket address and queue *          the data on it. */	    for (wp = (vp = peers) + maxpeers; vp < wp; vp++)		if (vp != up			&& vp -> udp_parent == up -> udp_parent		        && bcmp ((char *) &vp -> udp_peer, (char *) sock,				 sizeof *sock) == 0)		    break;	    if (vp >= wp &&	       (vp = &peers[up -> udp_parent]) -> udp_peer.sin_family != 0)	           {		   free ((char *) qb);		   continue;	    	   }#ifdef HULADEBUG  	    printf ("\n          queuing data on the found socket \n");#endif	    insque (qb, vp -> udp_queue.qb_back);	} /* end if FDSET *//*  *  Now reset all the file descriptors since they get modified. */    for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++)	if (up -> udp_parent != NOTOK && FD_ISSET (fd, &jfds))	    if (up -> udp_queue.qb_forw != &up -> udp_queue)		FD_SET (fd, rfds);	    else		FD_CLR (fd, rfds);    result = 0;    ifds = *rfds;    if (wfds)	for (fd = 0; fd < nfds; fd++)	    if (FD_ISSET (fd, wfds))		FD_SET (fd, &ifds);    if (efds)	for (fd = 0; fd < nfds; fd++)	    if (FD_ISSET (fd, efds))		FD_SET (fd, &ifds);    for (fd = 0; fd < nfds; fd++)	if (FD_ISSET (fd, &ifds))	    result++;/* *  Return the count of sockets that were read. */    return result;}#endif 	/* if HULA */#endif  /* if UDP  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -