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

📄 sockets.c

📁 lwip-1.4.0
💻 C
📖 第 1 页 / 共 5 页
字号:
  struct lwip_sock *sock;  int is_tcp = 0;  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));  sock = get_socket(s);  if (!sock) {    return -1;  }  if(sock->conn != NULL) {    is_tcp = netconn_type(sock->conn) == NETCONN_TCP;  } else {    LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL);  }  netconn_delete(sock->conn);  free_socket(sock, is_tcp);  set_errno(0);  return 0;}intlwip_connect(int s, const struct sockaddr *name, socklen_t namelen){  struct lwip_sock *sock;  err_t err;  const struct sockaddr_in *name_in;  sock = get_socket(s);  if (!sock) {    return -1;  }  /* check size, familiy and alignment of 'name' */  LWIP_ERROR("lwip_connect: invalid address", ((namelen == sizeof(struct sockaddr_in)) &&             ((name->sa_family) == AF_INET) && ((((mem_ptr_t)name) % 4) == 0)),             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);  name_in = (const struct sockaddr_in *)(void*)name;  if (name_in->sin_family == AF_UNSPEC) {    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s));    err = netconn_disconnect(sock->conn);  } else {    ip_addr_t remote_addr;    u16_t remote_port;    inet_addr_to_ipaddr(&remote_addr, &name_in->sin_addr);    remote_port = name_in->sin_port;    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s));    ip_addr_debug_print(SOCKETS_DEBUG, &remote_addr);    LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", ntohs(remote_port)));    err = netconn_connect(sock->conn, &remote_addr, ntohs(remote_port));  }  if (err != ERR_OK) {    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err));    sock_set_errno(sock, err_to_errno(err));    return -1;  }  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s));  sock_set_errno(sock, 0);  return 0;}/** * Set a socket into listen mode. * The socket may not have been used for another connection previously. * * @param s the socket to set to listening mode * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) * @return 0 on success, non-zero on failure */intlwip_listen(int s, int backlog){  struct lwip_sock *sock;  err_t err;  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog));  sock = get_socket(s);  if (!sock) {    return -1;  }  /* limit the "backlog" parameter to fit in an u8_t */  backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff);  err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog);  if (err != ERR_OK) {    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err));    sock_set_errno(sock, err_to_errno(err));    return -1;  }  sock_set_errno(sock, 0);  return 0;}intlwip_recvfrom(int s, void *mem, size_t len, int flags,        struct sockaddr *from, socklen_t *fromlen){  struct lwip_sock *sock;  void             *buf = NULL;  struct pbuf      *p;  u16_t            buflen, copylen;  int              off = 0;  ip_addr_t        *addr;  u16_t            port;  u8_t             done = 0;  err_t            err;  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags));  sock = get_socket(s);  if (!sock) {    return -1;  }  do {    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata));    /* Check if there is data left from the last recv operation. */    if (sock->lastdata) {      buf = sock->lastdata;    } else {      /* If this is non-blocking call, then check first */      if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) &&           (sock->rcvevent <= 0)) {        if (off > 0) {          /* update receive window */          netconn_recved(sock->conn, (u32_t)off);          /* already received data, return that */          sock_set_errno(sock, 0);          return off;        }        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s));        sock_set_errno(sock, EWOULDBLOCK);        return -1;      }      /* No data was left from the previous operation, so we try to get         some from the network. */      if (netconn_type(sock->conn) == NETCONN_TCP) {        err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf);      } else {        err = netconn_recv(sock->conn, (struct netbuf **)&buf);      }      LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n",        err, buf));      if (err != ERR_OK) {        if (off > 0) {          /* update receive window */          netconn_recved(sock->conn, (u32_t)off);          /* already received data, return that */          sock_set_errno(sock, 0);          return off;        }        /* We should really do some error checking here. */        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n",          s, lwip_strerr(err)));        sock_set_errno(sock, err_to_errno(err));        if (err == ERR_CLSD) {          return 0;        } else {          return -1;        }      }      LWIP_ASSERT("buf != NULL", buf != NULL);      sock->lastdata = buf;    }    if (netconn_type(sock->conn) == NETCONN_TCP) {      p = (struct pbuf *)buf;    } else {      p = ((struct netbuf *)buf)->p;    }    buflen = p->tot_len;    LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n",      buflen, len, off, sock->lastoffset));    buflen -= sock->lastoffset;    if (len > buflen) {      copylen = buflen;    } else {      copylen = (u16_t)len;    }    /* copy the contents of the received buffer into    the supplied memory pointer mem */    pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset);    off += copylen;    if (netconn_type(sock->conn) == NETCONN_TCP) {      LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen);      len -= copylen;      if ( (len <= 0) ||            (p->flags & PBUF_FLAG_PUSH) ||            (sock->rcvevent <= 0) ||            ((flags & MSG_PEEK)!=0)) {        done = 1;      }    } else {      done = 1;    }    /* Check to see from where the data was.*/    if (done) {      ip_addr_t fromaddr;      if (from && fromlen) {        struct sockaddr_in sin;        if (netconn_type(sock->conn) == NETCONN_TCP) {          addr = &fromaddr;          netconn_getaddr(sock->conn, addr, &port, 0);        } else {          addr = netbuf_fromaddr((struct netbuf *)buf);          port = netbuf_fromport((struct netbuf *)buf);        }        memset(&sin, 0, sizeof(sin));        sin.sin_len = sizeof(sin);        sin.sin_family = AF_INET;        sin.sin_port = htons(port);        inet_addr_from_ipaddr(&sin.sin_addr, addr);        if (*fromlen > sizeof(sin)) {          *fromlen = sizeof(sin);        }        MEMCPY(from, &sin, *fromlen);        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));        ip_addr_debug_print(SOCKETS_DEBUG, addr);        LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));      } else {#if SOCKETS_DEBUG        if (netconn_type(sock->conn) == NETCONN_TCP) {          addr = &fromaddr;          netconn_getaddr(sock->conn, addr, &port, 0);        } else {          addr = netbuf_fromaddr((struct netbuf *)buf);          port = netbuf_fromport((struct netbuf *)buf);        }        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s));        ip_addr_debug_print(SOCKETS_DEBUG, addr);        LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off));#endif /*  SOCKETS_DEBUG */      }    }    /* If we don't peek the incoming message... */    if ((flags & MSG_PEEK) == 0) {      /* If this is a TCP socket, check if there is data left in the         buffer. If so, it should be saved in the sock structure for next         time around. */      if ((netconn_type(sock->conn) == NETCONN_TCP) && (buflen - copylen > 0)) {        sock->lastdata = buf;        sock->lastoffset += copylen;        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf));      } else {        sock->lastdata = NULL;        sock->lastoffset = 0;        LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf));        if (netconn_type(sock->conn) == NETCONN_TCP) {          pbuf_free((struct pbuf *)buf);        } else {          netbuf_delete((struct netbuf *)buf);        }      }    }  } while (!done);  if (off > 0) {    /* update receive window */    netconn_recved(sock->conn, (u32_t)off);  }  sock_set_errno(sock, 0);  return off;}intlwip_read(int s, void *mem, size_t len){  return lwip_recvfrom(s, mem, len, 0, NULL, NULL);}intlwip_recv(int s, void *mem, size_t len, int flags){  return lwip_recvfrom(s, mem, len, flags, NULL, NULL);}intlwip_send(int s, const void *data, size_t size, int flags){  struct lwip_sock *sock;  err_t err;  u8_t write_flags;  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n",                              s, data, size, flags));  sock = get_socket(s);  if (!sock) {    return -1;  }  if (sock->conn->type != NETCONN_TCP) {#if (LWIP_UDP || LWIP_RAW)    return lwip_sendto(s, data, size, flags, NULL, 0);#else /* (LWIP_UDP || LWIP_RAW) */    sock_set_errno(sock, err_to_errno(ERR_ARG));    return -1;#endif /* (LWIP_UDP || LWIP_RAW) */  }  if ((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) {    if ((size > TCP_SND_BUF) || ((size / TCP_MSS) > TCP_SND_QUEUELEN)) {      /* too much data to ever send nonblocking! */      sock_set_errno(sock, EMSGSIZE);      return -1;    }  }  write_flags = NETCONN_COPY |    ((flags & MSG_MORE)     ? NETCONN_MORE      : 0) |    ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0);  err = netconn_write(sock->conn, data, size, write_flags);  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d size=%"SZT_F"\n", s, err, size));  sock_set_errno(sock, err_to_errno(err));  return (err == ERR_OK ? (int)size : -1);}intlwip_sendto(int s, const void *data, size_t size, int flags,       const struct sockaddr *to, socklen_t tolen){  struct lwip_sock *sock;  err_t err;  u16_t short_size;  const struct sockaddr_in *to_in;  u16_t remote_port;#if !LWIP_TCPIP_CORE_LOCKING  struct netbuf buf;#endif  sock = get_socket(s);  if (!sock) {    return -1;  }  if (sock->conn->type == NETCONN_TCP) {#if LWIP_TCP    return lwip_send(s, data, size, flags);#else /* LWIP_TCP */    LWIP_UNUSED_ARG(flags);    sock_set_errno(sock, err_to_errno(ERR_ARG));    return -1;#endif /* LWIP_TCP */  }  /* @todo: split into multiple sendto's? */  LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff);  short_size = (u16_t)size;  LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) ||             ((tolen == sizeof(struct sockaddr_in)) &&             ((to->sa_family) == AF_INET) && ((((mem_ptr_t)to) % 4) == 0))),             sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;);  to_in = (const struct sockaddr_in *)(void*)to;#if LWIP_TCPIP_CORE_LOCKING  /* Should only be consider like a sample or a simple way to experiment this option (no check of "to" field...) */  {    struct pbuf* p;    ip_addr_t *remote_addr;#if LWIP_NETIF_TX_SINGLE_PBUF    p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_RAM);    if (p != NULL) {#if LWIP_CHECKSUM_ON_COPY      u16_t chksum = 0;      if (sock->conn->type != NETCONN_RAW) {        chksum = LWIP_CHKSUM_COPY(p->payload, data, short_size);      } else#endif /* LWIP_CHECKSUM_ON_COPY */      MEMCPY(p->payload, data, size);#else /* LWIP_NETIF_TX_SINGLE_PBUF */    p = pbuf_alloc(PBUF_TRANSPORT, short_size, PBUF_REF);    if (p != NULL) {      p->payload = (void*)data;#endif /* LWIP_NETIF_TX_SINGLE_PBUF */      if (to_in != NULL) {        inet_addr_to_ipaddr_p(remote_addr, &to_in->sin_addr);        remote_port = ntohs(to_in->sin_port);      } else {        remote_addr = &sock->conn->pcb.raw->remote_ip;        if (sock->conn->type == NETCONN_RAW) {          remote_port = 0;        } else {          remote_port = sock->conn->pcb.udp->remote_port;        }      }      LOCK_TCPIP_CORE();      if (sock->conn->type == NETCONN_RAW) {        err = sock->conn->last_err = raw_sendto(sock->conn->pcb.raw, p, remote_addr);      } else {#if LWIP_UDP#if LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF        err = sock->conn->last_err = udp_sendto_chksum(sock->conn->pcb.udp, p,          remote_addr, remote_port, 1, chksum);#else /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */        err = sock->conn->last_err = udp_sendto(sock->conn->pcb.udp, p,          remote_addr, remote_port);#endif /* LWIP_CHECKSUM_ON_COPY && LWIP_NETIF_TX_SINGLE_PBUF */#else /* LWIP_UDP */        err = ERR_ARG;#endif /* LWIP_UDP */      }      UNLOCK_TCPIP_CORE();            pbuf_free(p);    } else {      err = ERR_MEM;    }  }#else /* LWIP_TCPIP_CORE_LOCKING */  /* initialize a buffer */  buf.p = buf.ptr = NULL;#if LWIP_CHECKSUM_ON_COPY

⌨️ 快捷键说明

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