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

📄 send.c

📁 用于嵌入式系统的TCP/IP协议栈
💻 C
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************//*                                                                     *//*   Module:  send.c                                                   *//*   Release: 2001.3                                                   *//*   Version: 99.0                                                     *//*   Purpose: send() and sendto() implementation                       *//*                                                                     *//*---------------------------------------------------------------------*//*                                                                     *//*               Copyright 1999, Blunk Microsystems                    *//*                      ALL RIGHTS RESERVED                            *//*                                                                     *//*   Licensees have the non-exclusive right to use, modify, or extract *//*   this computer program for software development at a single site.  *//*   This program may be resold or disseminated in executable format   *//*   only. The source code may not be redistributed or resold.         *//*                                                                     *//***********************************************************************/#include "../tcp_ipp.h"#include "../tcp/tcp.h"#include "../ip/ip.h"#include <string.h>/***********************************************************************//* Local Function Definitions                                          *//***********************************************************************//***********************************************************************//*    tcp_send: Transmit data over a TCP socket                        *//*                                                                     *//*      Inputs: sock = pointer to a TCP socket                         *//*              ptr = pointer to source buffer                         *//*              len = length of data                                   *//*              flags = behavior modifiers                             *//*                                                                     *//*     Returns: number written or -1 with errno set to error code      *//*                                                                     *//***********************************************************************/static int tcp_send(SOCKET sock, const ui8 *ptr, uint len, int flags){  int space, sboff;  /*-------------------------------------------------------------------*/  /* Check for available space in send buffer.                         */  /*-------------------------------------------------------------------*/  space = sock->sb_size - sock->sb_count;  TcpAssert(space >= 0);  if (space == 0)  {    /*-----------------------------------------------------------------*/    /* Return error if operation is non-blocking.                      */    /*-----------------------------------------------------------------*/    if (((sock->flags & SF_NONBLKNG) && (flags & MSG_WAITALL) == 0) ||        (flags & MSG_DONTWAIT))    {      NetError(sock, EWOULDBLOCK);      return -1;    }    /*-----------------------------------------------------------------*/    /* Else wait til there is space in buffer.                         */    /*-----------------------------------------------------------------*/    else    {      /*---------------------------------------------------------------*/      /* Wait for "data acknowledged" event.                           */      /*---------------------------------------------------------------*/      NetPendEvent(sock, SE_DATA_ACKED, sock->send_timeo);      /*---------------------------------------------------------------*/      /* Check if timed out or connection reset or aborted.            */      /*---------------------------------------------------------------*/      if (sock->error)      {        NetError(sock, sock->error);        return -1;      }      /*---------------------------------------------------------------*/      /* Redo space calculation.                                       */      /*---------------------------------------------------------------*/      space = sock->sb_size - sock->sb_count;      TcpAssert(space > 0);    }  }  /*-------------------------------------------------------------------*/  /* Check if sending of urgent data is requested.                     */  /*-------------------------------------------------------------------*/  if (flags & MSG_OOB)  {    /*-----------------------------------------------------------------*/    /* Urgent mode is entered only if last byte of write is included.  */    /*-----------------------------------------------------------------*/    if (space >= len)    {      sock->surg_seq = sock->snd_nxt + len - 1;      sock->flags |= (SF_SUPOK | SF_SENDFLG);    }  }  /*-------------------------------------------------------------------*/  /* Limit len to minimum of requested length and available space.     */  /*-------------------------------------------------------------------*/  len = min(len, space);  /*-------------------------------------------------------------------*/  /* Calculate starting offset of free space in send buffer.           */  /*-------------------------------------------------------------------*/  sboff = (sock->sb_start + sock->sb_count) % sock->sb_size;  /*-------------------------------------------------------------------*/  /* Copy data from user's buffer to socket's send buffer.             */  /*-------------------------------------------------------------------*/  if ((sboff + len) <= sock->sb_size)  {    memcpy(&sock->sbuf[sboff], ptr, len);  }  else  {    int len1 = sock->sb_size - sboff;    memcpy(&sock->sbuf[sboff], ptr, len1);    memcpy(&sock->sbuf[0], ptr + len1, len - len1);  }  /*-------------------------------------------------------------------*/  /* Update socket send data count.                                    */  /*-------------------------------------------------------------------*/  sock->sb_count += len;  /*-------------------------------------------------------------------*/  /* Try sending data if output state is "idle" or "transmitting".     */  /*-------------------------------------------------------------------*/  if (sock->out_state <= TCPO_XMIT)    TcpTryOut(sock);  return len;}/***********************************************************************//* Global Function Definitions                                         *//***********************************************************************//***********************************************************************//*      sendto: Write data to socket                                   *//*                                                                     *//*      Inputs: s = socket identifier                                  *//*              src = pointer to source data                           *//*              wanted = amount of data requested sent                 *//*              flags = option flags                                   *//*              to = pointer to optional destination address           *//*              tolen = sizeof(struct sockaddr_in)                     *//*                                                                     *//*     Returns: -1 if errors, else number of characters written        *//*                                                                     *//***********************************************************************/int sendto(int s, const void *src, int wanted, int flags, void *to,                                                               int tolen){  SOCKET sock = &Socks[s - 1];  int len, sent = -1;  struct sockaddr_in *addr = to;  Route *route;#if OS_PARM_CHECK  /*-------------------------------------------------------------------*/  /* Verify protocol has been initialized.                             */  /*-------------------------------------------------------------------*/  if (!Net.Initialized)  {    NetError(NULL, ENETDOWN);    return -1;  }  /*-------------------------------------------------------------------*/  /* Check for valid socket ID.                                        */  /*-------------------------------------------------------------------*/  if (InvalidHandle(s))  {    NetError(NULL, ENOTSOCK);    return -1;  }  /*-------------------------------------------------------------------*/  /* If used, check that source address is valid.                      */  /*-------------------------------------------------------------------*/  if (wanted && (src == NULL))  {    NetError(sock, EFAULT);    return -1;  }  /*-------------------------------------------------------------------*/  /* Check that requested data length is not negative.                 */  /*-------------------------------------------------------------------*/  if (wanted < 0)  {    NetError(sock, EINVAL);    return -1;  }#endif  /*-------------------------------------------------------------------*/  /* Gain exclusive socket API access and stack internals access.      */  /*-------------------------------------------------------------------*/  if (semPend(sock->api_access, WAIT_FOREVER))  {    NetError(NULL, ENOTSOCK);    return -1;  }  semPend(Net.IntSem, WAIT_FOREVER);  /*-------------------------------------------------------------------*/  /* Check if socket has been shutdown for sends.                      */  /*-------------------------------------------------------------------*/  if (sock->flags & SF_SND_SHUT)  {    NetError(sock, ESHUTDOWN);    goto send_exit;  }  /*-------------------------------------------------------------------*/  /* UDP socket write.                                                 */  /*-------------------------------------------------------------------*/  if (sock->type == SOCK_DGRAM)  {    NetBuf *buf;#if OS_PARM_CHECK    /*-----------------------------------------------------------------*/    /* Check for illegal flag options.                                 */    /*-----------------------------------------------------------------*/    if (flags & (MSG_DONTWAIT | MSG_OOB | MSG_WAITALL))    {      NetError(sock, EOPNOTSUPP);      goto send_exit;    }#endif    /*-----------------------------------------------------------------*/    /* If local port is not specified, pick one.                       */    /*-----------------------------------------------------------------*/    if (sock->local.sin_port == 0)    {      sock->local.sin_port = UdpNextPort();      if (sock->local.sin_port == 0)

⌨️ 快捷键说明

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