send 函式 (winsock2.h)

傳送函式會在連接的套接字上傳送數據。

語法

int WSAAPI send(
  [in] SOCKET     s,
  [in] const char *buf,
  [in] int        len,
  [in] int        flags
);

參數

[in] s

識別已連線套接字的描述項。

[in] buf

緩衝區的指標,其中包含要傳輸的數據。

[in] len

buf 參數所指向之緩衝區中數據的長度,以位元組為單位。

[in] flags

一組旗標,指定呼叫的進行方式。 這個參數是使用位 OR 運算元搭配下列任何值所建構。

意義
MSG_DONTROUTE
指定數據不應受限於路由。 Windows Sockets 服務提供者可以選擇忽略此旗標。
MSG_OOB
(數據流樣式套接字傳送 OOB 數據,例如僅SOCK_STREAM) 。

傳回值

如果沒有發生錯誤, send 會傳回傳送的位元組總數,可能小於 len 參數中要求傳送的數目。 否則,會傳回SOCKET_ERROR的值,並呼叫 WSAGetLastError 來擷取特定的錯誤碼。

錯誤碼 意義
WSANOTINITIALISED
使用這個函式之前,必須先進行成功的 WSAStartup 呼叫。
WSAENETDOWN
網路子系統失敗。
WSAEACCES
要求的位址是廣播位址,但未設定適當的旗標。 使用 SO_BROADCAST 套接字選項呼叫 setsockopt ,以啟用廣播位址的使用。
WSAEINTR
封鎖的 Windows Sockets 1.1 呼叫已透過 WSACancelBlockingCall 取消。
WSAEINPROGRESS
封鎖的 Windows Sockets 1.1 呼叫正在進行中,或服務提供者仍在處理回呼函式。
WSAEFAULT
buf 參數未完全包含在用戶位址空間的有效部分中。
WSAENETRESET
由於持續作用活動在作業進行中偵測到失敗,連線已中斷。
WSAENOBUFS
沒有可用的緩衝區空間。
WSAENOTCONN
未連接此通訊端。
WSAENOTSOCK
描述項不是套接字。
WSAEOPNOTSUPP
已指定MSG_OOB,但套接字不是數據流樣式,例如類型SOCK_STREAM、與此套接字相關聯的通訊網域不支援 OOB 數據,或套接字是單向的,而且僅支援接收作業。
WSAESHUTDOWN
套接字已關閉;在 叫用關機 之後,無法透過 設定 為 SD_SEND 或 SD_BOTH 在套接字上傳送。
WSAEWOULDBLOCK
套接字會標示為非封鎖,而要求的作業會封鎖。
WSAEMSGSIZE
套接字是訊息導向,而且訊息大於基礎傳輸所支援的最大值。
WSAEHOSTUNREACH
目前無法從此主機連線到遠端主機。
WSAEINVAL
套接字 尚未系結系結系結,或已指定未知旗標,或已為啟用SO_OOBINLINE的套接字指定MSG_OOB。
WSAECONNABORTED
此虛擬電路由於逾時或其他錯誤而終止。 此通訊端無法再使用,應用程式應予以關閉。
WSAECONNRESET
執行硬式或失敗關閉的遠端部分已重設此虛擬電路。 針對UDP套接字,遠端主機無法傳遞先前傳送的UDP數據報,並以「無法連線的埠」ICMP 封包回應。 此通訊端無法再使用,應用程式應予以關閉。
WSAETIMEDOUT
連線已卸除,因為網路失敗,或因為另一端的系統未通知而關閉。

備註

傳送函式可用來在連接的套接字上寫入傳出數據。

對於訊息導向套接字 (位址系列 AF_INETAF_INET6SOCK_DGRAM類型,以及 IPPROTO_UDP通訊協定,例如) ,請務必不要超過基礎提供者的最大封包大小。 呼叫 optname 參數設定為 SO_MAX_MSG_SIZE 以擷取套接字選項值,即可取得提供者的最大訊息封包大小。 如果數據太長而無法透過基礎通訊協議傳遞,則會傳回 錯誤 WSAEMSGSIZE ,而且不會傳輸任何數據。

成功完成 傳送 函式並不表示數據已成功傳遞並接收給收件者。 此函式只會指出已成功傳送數據。

如果傳輸系統內沒有可用的緩衝區空間來保存要傳輸的數據,除非套接字處於非封鎖模式,否則 傳送 將會封鎖。 在非封鎖數據流導向套接字上,寫入的位元組數目可以介於1到要求的長度之間,視用戶端電腦和伺服器電腦上的緩衝區可用性而定。 selectWSAAsyncSelectWSAEventSelect 函式可用來判斷何時可以傳送更多數據。

允許使用 len 參數為零的呼叫傳送,且實作會被視為成功。 在這種情況下, send 會以有效值傳回零。 針對訊息導向套接字,會傳送零長度傳輸數據報。

flags 參數可用來影響函式的行為,超出為相關聯套接字指定的選項。 傳送函式的語意取決於先前在 s 參數中指定的套接字上設定的任何選項,以及傳遞至傳送函式的 flags 參數。

呼叫 傳送的順序 也是緩衝區傳輸至傳輸層的順序。 由於某些 Winsock 提供者可能會將大型傳送要求分割成多個傳輸,因此不應該在同一個數據流導向套接字的相同數據流導向套接字上同時呼叫 send,這可能會導致來自相同數據流導向套接字上多個並行傳送要求的非預期數據交錯。

注意 發出封鎖的 Winsock 呼叫,例如 傳送時,Winsock 可能需要等候網路事件,才能完成呼叫。 在此情況下,Winsock 會執行可警示的等候,而異步過程調用 (APC) 排程在相同線程上可能會中斷。 在 APC 內發出另一個封鎖 Winsock 呼叫,中斷相同線程上持續封鎖 Winsock 呼叫會導致未定義的行為,而且永遠不會由 Winsock 客戶端嘗試。
 

範例程序代碼

下列範例示範如何使用 send 函式。
#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>

// Link with ws2_32.lib
#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 27015

int main() {

    //----------------------
    // Declare and initialize variables.
    int iResult;
    WSADATA wsaData;

    SOCKET ConnectSocket = INVALID_SOCKET;
    struct sockaddr_in clientService; 

    int recvbuflen = DEFAULT_BUFLEN;
    char *sendbuf = "Client: sending data test";
    char recvbuf[DEFAULT_BUFLEN] = "";

    //----------------------
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup failed with error: %d\n", iResult);
        return 1;
    }

    //----------------------
    // Create a SOCKET for connecting to server
    ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ConnectSocket == INVALID_SOCKET) {
        wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    //----------------------
    // The sockaddr_in structure specifies the address family,
    // IP address, and port of the server to be connected to.
    clientService.sin_family = AF_INET;
    clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    clientService.sin_port = htons( DEFAULT_PORT );

    //----------------------
    // Connect to server.
    iResult = connect( ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
    if (iResult == SOCKET_ERROR) {
        wprintf(L"connect failed with error: %d\n", WSAGetLastError() );
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
  }

    //----------------------
    // Send an initial buffer
    iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
    if (iResult == SOCKET_ERROR) {
        wprintf(L"send failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    printf("Bytes Sent: %d\n", iResult);

    // shutdown the connection since no more data will be sent
    iResult = shutdown(ConnectSocket, SD_SEND);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"shutdown failed with error: %d\n", WSAGetLastError());
        closesocket(ConnectSocket);
        WSACleanup();
        return 1;
    }

    // Receive until the peer closes the connection
    do {

        iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
        if ( iResult > 0 )
            wprintf(L"Bytes received: %d\n", iResult);
        else if ( iResult == 0 )
            wprintf(L"Connection closed\n");
        else
            wprintf(L"recv failed with error: %d\n", WSAGetLastError());

    } while( iResult > 0 );


    // close the socket
    iResult = closesocket(ConnectSocket);
    if (iResult == SOCKET_ERROR) {
        wprintf(L"close failed with error: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    WSACleanup();
    return 0;
}

範例程序代碼

如需另一個使用 send 函式的範例,請參閱 使用者入門 With Winsock

IrDA 套接字注意事項

  • 必須明確包含 Af_irda.h 頭檔。
Windows Phone 8:Windows Phone 8 和更新版本上的 Windows Phone Store 應用程式支援此函式。

Windows 8.1Windows Server 2012 R2:Windows 8.1、Windows Server 2012 R2 及更新版本上的 Windows 市集應用程式支援此函式。

規格需求

需求
最低支援的用戶端 Windows 8.1、Windows Vista [傳統型應用程式 |UWP 應用程式]
最低支援的伺服器 Windows Server 2003 [傳統型應用程式 |UWP 應用程式]
目標平台 Windows
標頭 winsock2.h
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

使用 Winsock 使用者入門

WSAAsyncSelect

WSAEventSelect

Winsock 函式

Winsock 參考

recv

recvfrom

select

sendto

socket