send 함수(winsock2.h)
send 함수는 연결된 소켓에 데이터를 보냅니다.
구문
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 연산자를 사용하여 생성됩니다.
값 | 의미 |
---|---|
|
데이터가 라우팅의 대상이 되어서는 안 되도록 지정합니다. Windows 소켓 서비스 공급자는 이 플래그를 무시하도록 선택할 수 있습니다. |
|
OOB 데이터(SOCK_STREAM 같은 스트림 스타일 소켓만 해당)를 보냅니다. |
반환 값
오류가 발생하지 않으면 send는 전송 된 총 바이트 수를 반환하며, 이는 len 매개 변수에서 전송하도록 요청된 수보다 작을 수 있습니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 코드를 검색할 수 있습니다.
오류 코드 | 의미 |
---|---|
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다. | |
네트워크 하위 시스템이 실패했습니다. | |
요청된 주소는 브로드캐스트 주소이지만 적절한 플래그가 설정되지 않았습니다. 브로드캐스트 주소를 사용할 수 있도록 SO_BROADCAST 소켓 옵션을 사용하여 setsockopt 를 호출합니다. | |
WSACancelBlockingCall을 통해 차단 Windows 소켓 1.1 호출이 취소되었습니다. | |
차단 Windows 소켓 1.1 호출이 진행 중이거나 서비스 공급자가 여전히 콜백 함수를 처리하고 있습니다. | |
buf 매개 변수는 사용자 주소 공간의 유효한 부분에 완전히 포함되지 않습니다. | |
해당 작업이 진행되는 동안 오류가 발생하여 연결이 끊겼습니다. | |
사용할 수 있는 버퍼 공간이 없습니다. | |
소켓이 연결되지 않았습니다. | |
설명자가 소켓이 아닙니다. | |
MSG_OOB 지정되었지만 소켓은 SOCK_STREAM 형식과 같은 스트림 스타일이 아니거나, OOB 데이터가 이 소켓과 연결된 통신 도메인에서 지원되지 않거나, 소켓이 단방향이며 수신 작업만 지원합니다. | |
소켓이 종료되었습니다. SD_SEND 또는 SD_BOTH 로 설정된 방법을 사용하여 종료가 호출된 후에는 소켓에 보낼 수 없습니다. | |
소켓이 차단 해제로 표시되고 요청된 작업이 차단됩니다. | |
소켓은 메시지 지향이며 메시지는 기본 전송에서 지원하는 최대값보다 큽습니다. | |
현재 이 호스트에서 원격 호스트에 연결할 수 없습니다. | |
소켓이 바인딩되지 않았거나 알 수 없는 플래그가 지정되었거나 SO_OOBINLINE 사용하도록 설정된 소켓에 대해 MSG_OOB 지정되었습니다. | |
가상 회로가 시간 초과 또는 기타 오류로 인해 종료되었습니다. 더 이상 소켓을 사용할 수 없으므로 응용 프로그램이 소켓을 닫아야 합니다. | |
가상 회로가 하드 또는 중단한 닫기를 실행하는 원격 쪽에서 재설정되었습니다. UDP 소켓의 경우 원격 호스트가 이전에 보낸 UDP 데이터그램을 배달할 수 없었고 "포트 연결할 수 없음" ICMP 패킷으로 응답했습니다. 더 이상 소켓을 사용할 수 없으므로 응용 프로그램이 소켓을 닫아야 합니다. | |
네트워크 오류 또는 다른 쪽 끝의 시스템이 예고 없이 중단되었기 때문에 연결이 끊어졌습니다. |
설명
send 함수는 연결된 소켓에 나가는 데이터를 쓰는 데 사용됩니다.
메시지 지향 소켓( AF_INET 또는 AF_INET6 주소 패밀리, SOCK_DGRAM 유형 및 IPPROTO_UDP 프로토콜)의 경우 기본 공급자의 최대 패킷 크기를 초과하지 않도록 주의해야 합니다. 공급자의 최대 메시지 패킷 크기는 optname 매개 변수가 SO_MAX_MSG_SIZE 설정된 getsockopt를 호출하여 소켓 옵션 값을 검색하여 가져올 수 있습니다. 데이터가 기본 프로토콜을 통해 원자성으로 전달하기에 너무 긴 경우 WSAEMSGSIZE 오류가 반환되고 데이터가 전송되지 않습니다.
송신 함수가 성공적으로 완료되었다고 해서 데이터가 수신자에게 성공적으로 전달되고 수신되었음을 의미하지는 않습니다. 이 함수는 데이터가 성공적으로 전송되었음을 나타냅니다.
전송 시스템 내에서 전송할 데이터를 저장할 수 있는 버퍼 공간이 없는 경우 소켓이 차단 해제 모드에 배치되지 않는 한 전송 이 차단됩니다. 비 차단 스트림 지향 소켓에서 기록된 바이트 수는 클라이언트 및 서버 컴퓨터의 버퍼 가용성에 따라 1에서 요청된 길이 사이일 수 있습니다. select, WSAAsyncSelect 또는 WSAEventSelect 함수를 사용하여 더 많은 데이터를 보낼 수 있는 시기를 결정할 수 있습니다.
len 매개 변수가 0인 send를 호출하는 것은 허용되며 구현에서 성공으로 처리됩니다. 이러한 경우 send 는 0을 유효한 값으로 반환합니다. 메시지 지향 소켓의 경우 길이가 0인 전송 데이터그램이 전송됩니다.
flags 매개 변수를 사용하여 연결된 소켓에 대해 지정된 옵션 외에 함수의 동작에 영향을 줄 수 있습니다. send 함수의 의미 체계는 이전에 s 매개 변수에 지정된 소켓에 설정된 옵션과 send 함수에 전달된 flags 매개 변수에 의해 결정됩니다.
송신 호출 순서는 버퍼가 전송 계층으로 전송되는 순서이기도 합니다. 일부 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 8.1 및 Windows 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 |