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

📄 tcpss.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:

            /* Store the number of bytes in this buffer. */
            work_buf->data_len = bc;

            /* Bump up the total count for this buffer chain. */
            buf_ptr->mem_total_data_len += bc;

            bytes_left -= bc;

            buffer += bc;
        }


        /* Update various conters and statistics. */
        prt->out.contain += (UINT16) bytes_to_move;

        nsent += (UINT16) bytes_to_move;

        numbytes -= bytes_to_move;

        /* Update the number of actual TCP data held in this packet. This will
           only be used if this packet is retransmitted. */
        buf_ptr->mem_tcp_data_len = (UINT16) buf_ptr->mem_total_data_len;

        /* 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 ( (TCPSS_Net_Send(prt, buf_ptr) > 0) && (prt->xmitFlag) )
        {
            UTL_Timerunset (CONTX, (UNSIGNED)prt->pindex, (INT32)1);
            prt->xmitFlag = NU_CLEAR;
        
            /* Clear the next packet pointer since this packet was sent. */
            wind->nextPacket = NU_NULL;
        }
    }

    /* While there is more data to send break it up into individual packets 
       and send it. */
    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_left = numbytes;
        else
            bytes_left = MAX_SEGMENT_LEN;

        /* Make sure there are enough buffers left before we take 
           another one. We must leave some for RX. */
        if ((MAX_BUFFERS - MEM_Buffers_Used) <= NET_FREE_BUFFER_THRESHOLD)
        {
            /* Get out of the loop. */
            numbytes = 0;

            /* Set the status. */
            *status = NU_NO_BUFFERS;

            continue;
        }

        /* Allocate a buffer chain to stick the data in. */
        buf_ptr = MEM_Buffer_Chain_Dequeue (&MEM_Buffer_Freelist, 
            (INT32)(bytes_left + NET_MAX_TCP_HEADER_SIZE));

        /* Compute the data size with the TCP header. */
        buf_ptr->mem_total_data_len = bytes_left;

        buf_ptr->mem_tcp_data_len = (UINT16) bytes_left;

        /* Clear the flags field. */
        buf_ptr->mem_flags = 0;

        work_buf = buf_ptr;

        /* Copy the data into the buffer chain. */
        while (bytes_left && work_buf)
        {
            /* Check to see if the current buffer is the first one in the chain.
               The first one is treated differntly from the rest. */
            if (work_buf == buf_ptr)
            {
                /* Set the number of bytes to copy to the minimum of the space 
                   available or the bytes left. */ 
                bc = (bytes_left < (NET_PARENT_BUFFER_SIZE - NET_MAX_TCP_HEADER_SIZE))
                    ? bytes_left : (NET_PARENT_BUFFER_SIZE - NET_MAX_TCP_HEADER_SIZE);
                
                /* Point to where the data will begin. */
                work_buf->data_ptr = (work_buf->mem_parent_packet + NET_MAX_TCP_HEADER_SIZE);
            }
            else
            {
                /* Set the number of bytes to copy to the minimum of the space
                   available or the bytes left. */
                bc = (bytes_left < NET_MAX_BUFFER_SIZE) ? bytes_left : NET_MAX_BUFFER_SIZE;
                
                /* Point to where the data will begin. */
                work_buf->data_ptr = work_buf->mem_packet;
            }

            /* Copy the data into the buffer. */
            NU_BLOCK_COPY(work_buf->data_ptr, buffer, (unsigned int)bc);
            
            /* update the number of bytes still to be copied. */
            bytes_left -= bc;

            /* Initialize the number of bytes of data in this buffer. */
            work_buf->data_len = bc;

            /* Advance the pointer to the userd data. */
            buffer += bc;

            /* Point to the next buffer in the chain. */
            work_buf = work_buf->next_buffer;
        }

        /* Initialize the list that this packet will be deallocated to when
           transmission is complete.
        */
        buf_ptr->mem_dlist = &prt->out.packet_list;
        buf_ptr->mem_port_index = prt->pindex;

        /* Initialize the data length of this buffer. */
        buf_ptr->mem_option_len = 0;

        /* Preserve the number of bytes that we will attempt to send. */
        temp_len = (UINT16) buf_ptr->mem_total_data_len;

        /* 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 ( ((s = TCPSS_Net_Send(prt, buf_ptr)) > 0) && (prt->xmitFlag) )
        {
            UTL_Timerunset (CONTX, (UNSIGNED)prt->pindex, (INT32)1);
            prt->xmitFlag = NU_CLEAR;

            /* Clear the next packet pointer since this packet was sent. */
            wind->nextPacket = NU_NULL;
        }
        else if (s == 0)
            wind->nextPacket = buf_ptr;
        else if (s < 0)
        {
            /* Return the error code. */
            *status = s;
            break;
        }

        /* Now that the data has been successfully sent update the various 
           counters. */
        /* Update the amount of data in this port. */
        prt->out.contain += temp_len;

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

        /* Increment the number of bytes we have sent so far. */
        nsent += temp_len;

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


        if(wind->nextPacket != NU_NULL)
        {
            prt->xmitFlag = NU_SET;

            UTL_Timerset(CONTX, (UNSIGNED)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(nsent+sent_by_wp);

} /* end TCPSS_Net_Write() */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TCPSS_Net_Listen                                                
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Listen to a TCP port number and make the connection automatically 
*       when the SYN packet comes in.  The TCP layer will notify the 
*       higher layers with a CONOPEN event.  Save the port number returned
*       to refer to this connection.                                      
*                                                                       
*       example usage : portnum=netlisten ( service )                     
*                                                                       
*       Returns < 0 if error                                              
*
*   INPUTS
*
*       serv
*       *tcp_check
*
*   OUTPUTS
*
*       -1
*       -2
*       The port number
*                                                                       
*************************************************************************/
STATUS  TCPSS_Net_Listen(UINT16 serv, struct pseudotcp *tcp_check)
{
    INT             pnum;
    INT16           i, pos;
    TCP_PORT        *prt;
    INT32           tval, tmp, tmnc;
    SCK_SOCKADDR_IP *dest;

    /* Init */
    pos  = NU_IGNORE_VALUE;
    tval = NU_NULL;

    /* Try to make a new port. */
    if((pnum = TCP_Make_Port())<0)
    {
        /* If make port failed we will try to reuse one that is in the
           time wait state and has timedout. */
        if (pnum == -1)
        {
            /* Get the current clock value. */
            tmnc = NU_Retrieve_Clock();

            /* Loop through the port list checking for timedout ports.
               Note we will use the oldest timedout port. */
            for(i = 0; (!(i >= TCP_MAX_PORTS) && (TCP_Ports[i] != NU_NULL)); i++)
            {
                /* Is this port in the time wait state. */
                if (TCP_Ports[i]->state == STWAIT)
                {
                    /* Compare the timeout time and the current time. */
                    tmp = labs(INT32_CMP(tmnc, TCP_Ports[i]->out.lasttime));

                    /* Has this port timedout. */
                    if (tmp > tval)
                    {
                        /* Save this ports time value. This is used in finding
                           the oldeset timedout port. */
                        tval = tmp;

                        /* Store it position for use below. */
                        pos = i;

                    } /* end if the port timedout */

                } /* end if the port is in the time wait state */

            } /* end loop search through the ports */

            /* Did we loop through all the ports or not find one that
               has timedout. */
            if((pos >= TCP_MAX_PORTS) || (pos == NU_IGNORE_VALUE))
            {
                NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);

                return(-2);
            }

            /* Save the position in the port list. */
            pnum = pos;
        }

    } /* end if there was no port returned from TCP_Make_Port */


    /* Make sure this port entry is valid. */
    if(NU_NULL==(prt=TCP_Ports[pnum]))
         return(-2);

    /* Create the socket that will be used by the application that accepts
       this connection. */
    if ( (prt->p_socketd = SCK_Create_Socket(NU_PROTO_TCP)) < 0)
    {
        prt->state = SCLOSED;
        return (-2);
    }

    /* Store the port index. */
    SCK_Sockets[prt->p_socketd]->s_port_index = pnum;

    /* Point to the destination. */
    dest = (SCK_SOCKADDR_IP *) &prt->tp_route.rt_ip_dest;
    dest->sck_family = SK_FAM_IP;
    dest->sck_len = sizeof (*dest);
    dest->sck_addr = LONGSWAP(tcp_check->source);

    IP_Find_Route(&prt->tp_route);

    if (prt->tp_route.rt_route == NU_NULL)
    {
        prt->state = SCLOSED;
        return -1;
    }

    prt->tcp_laddr = LONGSWAP(tcp_check->dest);
           
    prt->in.port=serv;
    prt->out.port=0;                        /* accept any outside port #*/
    prt->in.lasttime=NU_Retrieve_Clock();   /* set time we started */


    prt->state  = SLISTEN;
    prt->credit = WINDOW_SIZE;           /* default value until changed */

    return(pnum);

} /* end TCPSS_Net_Listen() */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TCPSS_Net_Xopen        
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Open a network socket for the user to *machine* using             
*       port *service*.  The rest of the parameters are self-explanatory. 
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *machine                                                         
*       service                                                          
*       socketd                                                          
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       pnum                                                             
*       NU_NO_PORT_NUMBER                                                
*       -1                                                               
*       -4                                                               
*                                                                       

⌨️ 快捷键说明

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