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

📄 user.c

📁 mcf5307实验源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
            numbytes = (wind->size - wind->contain);
    }

    if (numbytes <= 0)
    {
        /* Check to see if a window probe is needed.  A probe is only needed if
           the foreign port has advertised a window of 0 and there is no
           unacknowledged data. */
        if ( (wind->size == 0) && (wind->nxt == wind->ack) )
        {
            if ((sent_by_wp=windowprobe(prt, nbytes, buffer)) == NU_NOT_ESTAB)
            {
                *status = NU_NOT_CONNECTED;
                return(0);
            }

            /* Advance the buffer pointer beyond the data that has already been
               sent. */
            buffer += sent_by_wp;

            numbytes = nbytes - sent_by_wp;
            if (numbytes > (wind->size - wind->contain))
                numbytes = wind->size - wind->contain;
        }
        else
        {
            *status = NU_WINDOW_FULL;
            return(0);
        }
    }

    /* Are there any packets that contain data but have not yet been sent.
       Should never be more than one of these. */
    if (wind->nextPacket != NU_NULL)
    {
        /* How much data can be copied into this partially filled buffer. */
        if(numbytes > (int32)(MAX_SEGMENT_LEN - wind->nextPacket->data_len))
            bytes_to_move = MAX_SEGMENT_LEN - wind->nextPacket->data_len;
        else
            bytes_to_move = numbytes;

        /* Move the data into the buffer. */
        memcpy((void *)(wind->nextPacket->data_ptr +
                         wind->nextPacket->data_len),
                (const void *)buffer, bytes_to_move);

        /* Update various conters and statistics. */
        wind->nextPacket->data_len += (uint16)bytes_to_move;
        prt->out.contain += (uint16)bytes_to_move;
        nsent += (uint16)bytes_to_move;
        numbytes -= bytes_to_move;
        buffer += bytes_to_move;
    }


    bytes_to_move = MAX_SEGMENT_LEN;

    while (numbytes > 0)
    {
        /* If there is not enough data left to fill a complete buffer,
           update bytes_to_move with the number of bytes left. */
        if (numbytes <= MAX_SEGMENT_LEN)
           bytes_to_move = numbytes;

        /* Check for ODH enabled. */
        if (prt->odh_flag & NU_ODH_TRANSMIT)
        {

            /* If ODH is already enabled then simply derive the pointer to the
               beginnig of the packet buffer. */
            buf_ptr = (BUFFER *)(buffer - sizeof(DLAYER)
                                                   - sizeof(IPLAYER)
                                                   - sizeof(TCPLAYER)
                                                   - PQ_HEADER_SIZE);

            /* Set up the next packet pointer. */
            wind->nextPacket = buf_ptr;
        }
        else
        {
            /* Allocate a buffer */
            buf_ptr = allocate_buffer(prt);

            /* If no buffers available then return. */
            if (buf_ptr == NU_NULL)
            {
                *status = NU_NO_BUFFERS;
                numbytes = 0;
                continue;
            }

            /* Point the data pointer at an offset into the buffer large
               enough to leave room for the header information. */
            buf_ptr->data_ptr = buf_ptr->packet + (sizeof(DLAYER) +
                                               sizeof(IPLAYER) +
                                               sizeof(TCPLAYER));

            /* move the data into the packet buffer */
            memcpy((void *)buf_ptr->data_ptr, (const void *)buffer,
                    bytes_to_move);

            if(wind->nextPacket == NU_NULL)
                wind->nextPacket = buf_ptr;
        }

        /* Initialize the data length of this buffer. */
        buf_ptr->data_len = (uint16)bytes_to_move;
        buf_ptr->option_len = 0;

        /* Update the amount of data in this port. */
        prt->out.contain += (uint16)bytes_to_move;

        /* Update the number of packets in this port. */
        prt->out.num_packets++;

        /* Increment the number of bytes we have sent so far. */
        nsent += (uint16)bytes_to_move;

        /* Decrease the amount of data left before the caller's request has
         * been filled. */
        numbytes -= bytes_to_move;

        /* Move the location from which we are copying forward. */
        buffer += bytes_to_move;
    }


    /* Now that the data has been broken up into packets, send it.  If some data
       was sent and there was a timer event set to transmit data, then clear the
       event.  The data that the event was intended for has just been sent. */
    if ( (netsend(prt) > 0) && (prt->xmitFlag) )
    {
        Stimerunset (CONCLASS, CONTX, prt->pindex, (int32)1);
        prt->xmitFlag = NU_CLEAR;
    }

    /*  There is some untransmitted data, set up a timer to make sure that it
        gets transmitted. */
    if(wind->nextPacket != NU_NULL)
    {
        prt->xmitFlag = NU_SET;

        Stimerset(CONCLASS, CONTX, prt->pindex, SWSOVERRIDE, (int32)0);
    }

    /* If the other side has sent a FIN then indicate that the connection is
       closing. */
    if (prt->state == SCWAIT)
        *status = NU_CLOSING;

    return((int16)(nsent+sent_by_wp));

} /* end netwrite */

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netqlen(int16)                                                   */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Returns the number of bytes waiting to be read from the incoming    */
/*   queue or<0 if error.                                                */
/*                                                                       */
/* CALLED BY                                                             */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*                                                                       */
/*************************************************************************/
int16 netqlen(int16 pnum)
{
      if(portlist[pnum]==NU_NULL)
           return(-2);
           
      return((int16)portlist[pnum]->in.contain);
}

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netroom(int16)                                                   */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Returns the number of bytes left in the output buffer for port      */
/*   *pnum*. Returns <0 if error occurs.                                 */
/*                                                                       */
/* CALLED BY                                                             */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*                                                                       */
/*************************************************************************/
int16 netroom(int16 pnum)
{
      if(portlist[pnum]==NU_NULL || portlist[pnum]->state!=SEST)
           return(-2);
           
      return((int16)(WINDOWSIZE-portlist[pnum]->out.contain));
}

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netsetip(unsigned char *)                                        */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Set a new ip number.  This goes through and changes all sorts of ip */
/*   numbers.  This routine assumes that there are currently NO open     */
/*   tcp connections.                                                    */
/*                                                                       */
/* CALLED BY                                                             */
/*      parse_bootpacket                                                 */
/*      bootp                                                            */
/*      Snetinit                                                         */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*                                                                       */
/*************************************************************************/
void netsetip(unsigned char *st)
{
      /*
      *  change all dependent locations relating to the IP number
      *  don't worry about open connections, they must be closed by higher 
      *  layer
      */
      /* main ip number */
      memcpy ((void *)nnipnum, (const void *)st, 4);
      /* arp */
      memcpy ((void *)arp.spa, (const void *)nnipnum, 4);
      /* ip source */
      memcpy ((void *)blankip.i.ipsource, (const void *)nnipnum, 4);
}

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netgetip(unsigned char *)                                        */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Sets *st* to the current up number                                  */
/*                                                                       */
/* CALLED BY                                                             */
/*      Snetinit                                                         */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */
/*                                                                       */
/*************************************************************************/
void netgetip(unsigned char *st)
{
      memcpy ((void *)st, (const void *)nnipnum, 4);
}

/*************************************************************************/
/*                                                                       */
/* FUNCTION                                                              */
/*                                                                       */
/*      netsetbroad(unsigned char *)                                     */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*   Set the network broadcast IP address.                               */
/*                                                                       */
/* CALLED BY                                                             */
/*      Snetinit                                                         */
/*                                                                       */
/* CALLS                                                                 */
/*                                                                       */

⌨️ 快捷键说明

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