📄 send.c
字号:
{ NetError(sock, EMFILE); goto send_exit; } } /*-----------------------------------------------------------------*/ /* Check if no destination address is supplied. */ /*-----------------------------------------------------------------*/ if (addr == NULL) { /*---------------------------------------------------------------*/ /* Socket must be connected. */ /*---------------------------------------------------------------*/ if ((sock->flags & SF_CONNECTED) == FALSE) { NetError(sock, ENOTCONN); goto send_exit; } /*---------------------------------------------------------------*/ /* Use connected address as destination address. */ /*---------------------------------------------------------------*/ addr = &sock->remote; /*---------------------------------------------------------------*/ /* Find route for this address, using cached route if available. */ /*---------------------------------------------------------------*/ if (sock->route) route = sock->route; else { route = RtSearch(addr->sin_addr.s_addr); if (route == NULL) { ++Stats.IpOutNoRoutes; NetError(sock, ENETUNREACH); goto send_exit; } sock->route = route; } } /*-----------------------------------------------------------------*/ /* Else destination address is supplied. */ /*-----------------------------------------------------------------*/ else {#if OS_PARM_CHECK /*---------------------------------------------------------------*/ /* Verify address length is correct. */ /*---------------------------------------------------------------*/ if (tolen != sizeof(struct sockaddr_in)) { NetError(sock, EFAULT); goto send_exit; } /*---------------------------------------------------------------*/ /* Verify destination IP address and port number are not zero. */ /*---------------------------------------------------------------*/ if ((addr->sin_addr.s_addr == INADDR_ANY) || (addr->sin_port == 0)) { NetError(sock, EDESTADDRREQ); goto send_exit; } /*---------------------------------------------------------------*/ /* Verify address family is AF_INET. */ /*---------------------------------------------------------------*/ if (addr->sin_family != AF_INET) { NetError(sock, EAFNOSUPPORT); goto send_exit; }#endif /*---------------------------------------------------------------*/ /* If cached route exists for this destination address, use it. */ /*---------------------------------------------------------------*/ if (sock->route && (sock->remote.sin_addr.s_addr == addr->sin_addr.s_addr)) { route = sock->route; } /*---------------------------------------------------------------*/ /* Else look up route and cache it if socket is not connected. */ /*---------------------------------------------------------------*/ else { route = RtSearch(addr->sin_addr.s_addr); if (route == NULL) { ++Stats.IpOutNoRoutes; NetError(sock, ENETUNREACH); goto send_exit; } if ((sock->flags & SF_CONNECTED) == FALSE) sock->route = route; } } /*-----------------------------------------------------------------*/ /* If DONTROUTE is set, verify that route is direct. */ /*-----------------------------------------------------------------*/ if (((sock->flags & SF_DONTROUTE) || (flags & MSG_DONTROUTE)) && (route->flags & RT_GATEWAY)) { ++Stats.IpOutNoRoutes; NetError(sock, ENETUNREACH); goto send_exit; } /*-----------------------------------------------------------------*/ /* If destination is broadcast, verify socket options allow it. */ /*-----------------------------------------------------------------*/ if ((route->flags & RT_BRDCST) && !(sock->flags & SF_BROADCAST)) { NetError(sock, EACCES); goto send_exit; } /*-----------------------------------------------------------------*/ /* Clip the amount sent to the maximum possible size. */ /*-----------------------------------------------------------------*/ sent = min(wanted, TCP_BIG_SIZE - (UDP_HLEN + IPMHLEN + NIMHLEN)); /*-----------------------------------------------------------------*/ /* Get a buffer for the outbound datagram. */ /*-----------------------------------------------------------------*/ buf = tcpGetBuf(NIMHLEN + IPMHLEN + UDP_HLEN + sent); if (buf == NULL) { sent = -1; NetError(sock, ENOBUFS); goto send_exit; } /*-----------------------------------------------------------------*/ /* Copy source data to the datagram and send it on its way. */ /*-----------------------------------------------------------------*/ memcpy((char *)buf->ip_data + UDP_HLEN, src, sent); UdpSend(sock, addr, buf, sent, route); /*-----------------------------------------------------------------*/ /* Check whether datagram was truncated. */ /*-----------------------------------------------------------------*/ if (sent < wanted) { sent = -1; NetError(sock, EMSGSIZE); goto send_exit; } } /*-------------------------------------------------------------------*/ /* TCP socket write. */ /*-------------------------------------------------------------------*/ else { /*-----------------------------------------------------------------*/ /* Check for illegal flag options. */ /*-----------------------------------------------------------------*/ if ((flags & MSG_DONTWAIT) && (flags & MSG_WAITALL)) { NetError(sock, EFAULT); goto send_exit; } /*-----------------------------------------------------------------*/ /* Verify that socket is connected. */ /*-----------------------------------------------------------------*/ if ((sock->flags & SF_CONNECTED) == FALSE) { if (sock->error == 0) sock->error = ENOTCONN; NetError(sock, sock->error); goto send_exit; } /*-----------------------------------------------------------------*/ /* Loop to write the requested number of bytes. */ /*-----------------------------------------------------------------*/ for (sent = 0; sent < wanted; sent += len) { /*---------------------------------------------------------------*/ /* Attempt to send data over TCP socket. */ /*---------------------------------------------------------------*/ len = tcp_send(sock, src, wanted - sent, flags); /*---------------------------------------------------------------*/ /* Check if error occurred. */ /*---------------------------------------------------------------*/ if (len < 0) { /*-------------------------------------------------------------*/ /* If some data has been successfully sent, just break. */ /*-------------------------------------------------------------*/ if (sent) break; /*-------------------------------------------------------------*/ /* Else go to error exit. */ /*-------------------------------------------------------------*/ else { sent = -1; goto send_exit; } } /*---------------------------------------------------------------*/ /* Update the source pointer. */ /*---------------------------------------------------------------*/ src = (char *)src + len; } } /*-------------------------------------------------------------------*/ /* Release exclusive API and internals access. Return status code. */ /*-------------------------------------------------------------------*/send_exit: semPost(sock->api_access); semPost(Net.IntSem); return sent;}/***********************************************************************//* send: Write data to socket *//* *//* Inputs: s = socket identifier *//* src = pointer to source data *//* wanted = amount of data requested sent *//* flags = option flags *//* *//* Returns: -1 if errors, else number of characters written *//* *//***********************************************************************/int (send)(int s, const void *src, int wanted, int flags){ return sendto(s, src, wanted, flags, 0, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -