📄 sockets.c
字号:
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 + -