반응형

WSASend

WSASend 함수는 접속된 상대방 소켓에게 지정한 데이터를 보내는 함수입니다.

int WSASend (
        SOCKET  
s,
        LPWSABUF  
lpBuffers,
        DWORD  
dwBufferCount,
        LPDWORD  
lpNumberOfBytesSent,
        DWORD  
dwFlags,
        LPWSAOVERLAPPED  
lpOverlapped,
        LPWSAOVERLAPPED_COMPLETION_ROUTINE  
lpCompletionROUTINE
);

 

Parameters

s
[입력] 접속된 소켓을 가리키는 소켓 기술자

lpBuffers
[입력]
WSABUF 구조체의 포인터. WSABUF 구조체는 버퍼의 포인터와 퍼퍼의 길이를 나타내는 멤버로 구성되는 구조체로 이 구조체의 배열을 포인트 해서 넘겨줍니다.

dwBufferCount
[입력] lpBuffer 배열로 지정된
WSABUF 구조체의 갯수

lpNumberOfBytesSent
[출력] 이 함수의 호출로 인해서 전송된 바이트의 갯수를 포인트 합니다.

dwFlags
[입력] 어떻한 방식으로 전송을 수행 할 것인지 설정하는 플래그

lpOverlapped
[입력]
WSAOVERLAPPED 구조체의 포인터 ("넌오버랩" 소켓에 대해서는 무시됩니다.)

lpCompletionRoutine
[입력] 전송연산이 완료되었을 때 호출되는 전송완료 루틴에 대한 포인터입니다. ("넌오버랩" 소켓에서는 무시됩니다.)

 

Remarks

WSASend 함수는 기존의 send 함수의 기능을 모두 다 수행 하면서, 아래의 두가지 항목을 추가적으로 지원합니다.

    1. 중복된 전송 연산을 수행하도록 중복(overlapped)소켓을 가지고 작업할 수 있는 기능

    2. 여러개의 전송 버퍼를 두어 전송 할 수 있는 기능

WSASend 함수는 s 매개변수로 로 지정된 접속지향형 소켓에서 한 개 또는 그 이상의 데이터를 전송 하기위해서 사용하는 함수입니다. 이 함수는 비접속 지향형 소켓(SOCK_DGRAM 과 같은 소켓이겠죠?) 에서도 사용 가능합니다. 하지만, 이렇게 사용하려 하는 경우에, 소켓은 connect 함수나 WSAConnect 함수에 의해서 상대방 어드레스가 지정되어 있어야 합니다.

오버랩 소켓(WSASocket 함수를 WSA_FLAG_OVERLAPPED 플래그를 두어 생성한 소켓)은 오버랩 입/출력을 사용하여 정보를 전송하게 됩니다. 하지만, lpOverlappedlpCompleteRoutine 매개변수가 NULL인 경우 소켓은 넌-오버랩 소켓으로 간주되어 처리되게 됩니다.

전송하는데 지정된 버퍼가 다 사용되었을 때 완료루틴이 호출되거나, 이벤트 객체가 셋팅되는 방식으로 작업이 완료 되었다는 것을 알 수 있습니다. 만약 작업이 바로 완료되지 않는 경우엔 완료루틴이나, WSAGetOverlappedResult 함수에 의해서 마지막 완료 상태를 얻어낼 수 있습니다.

넌-오버랩 소켓에서는 마지막 두 매개변수(lpOverlapped, lpCompletetionRoutine)은 무시됩니다. 그리고, WSASend 함수는 send 함수와 같은 동작을 하도록 사용되어 집니다. 데이터는 지정된 버퍼로부터 전송버퍼로 복사됩니다. 만약 소켓이 비동기 모드인 스트림 소켓이고, 전송버퍼에 충분한 공간이 남아있지 않다면, WSASend 함수는 전송하는데 사용되었던 버퍼 만큼만을 반환 할 것입니다. 블록킹 소켓의 경우는 전송버퍼 공간이 남아서 지정된 버퍼를 전송버퍼로 다 복사 할 때 까지 블록킹 됩니다.

lpBuffers 매개변수에 의해서 포인트되는 WSABUF 구조체 배열은 일시적인 공간입니다. 전송연산이 오버랩 처리를 완료했다면, 이 공간은 서비스 프로바이더의 책임입니다. 즉, WSASend 함수가 반환하기전에 이 WSABUF 구조체를 서비스 프로바이더가 캡쳐해야 하는 것이죠. 이러한 처리방식은 WSABUF 배열을 스택기반으로 이루어질 수 있도록 하게 됩니다.

메시지 지향형 소켓(비접속 지향형 소켓)의 경우 서비스 프로바이더에서 지원할 수 있는 메시지의 최대 크기를 넘지 않도록 조심해야 합니다. 이 최대값은 SO_MAX_MSG_SIZE 옵션으로 얻어낼 수 있죠. 만약 전송할 데이터가 전송하기에 너무 큰데이터라면, WSAEMSGSIZE 라는 에러를 반환 하게 됩니다. 글구... 아무런 데이터도 전송되지 않게 됩니다.

Note : WSASend 함수를 성공적으로 수행 했다고 해서 데이터가 성공적으로 상대방에게 전송되었다고 확신 할 수는 없습니다.

dwFlags 매개변수는 함수를 호출했을 때 어떻게 데이터를 전송할 것인지 세부적인 함수의 행동을 설정하는데 사용하는 값입니다. 즉, 이 함수의 동작을 결정하는 것은 소켓 옵션과 dwFlags 매개변수라고 할 수 있습니다. dwFlag 매개변수에 들어가는 값은 아래에 제시한 값들을 OR 로 구성하여 넘겨주면 됩니다.

Value Meaning
MSG_DONTROUTE 데이터를 라우팅하도록 하지 않도록 명시합니다. 윈도즈 소켓 서비스 프로바이더는 이 플래그를 무시할 수 있습니다.
MSG_OOB SOCK_STREAM으로 생성한 연결지향형 소켓에서 out-of-band 데이터를 전송하는데 사용되는 값입니다.
MSG_PARTIAL lpBuffers 매개변수가 부분적인 메시지만을 담도록 명시합니다. 만약 부분적인 메시지 전송을 지원하지 않는 경우에는 WSAEOPNOTSUPP 에러코드를 반환 할 것입니다.

 

Overlapped socket I/O

오버랩 연산이 바로 완료 되었다면, WSASend 함수는 0 값을 반환 합니다. 그리고, lpNumberOfBytesSent 매개변수는 전송된 바이트의 수를 포인트 합니다. 오버랩 연산이 성공적으로 시작되었으나, 나중에 완료될 것이라면, WSASend 함수는 SOCKET_ERROR을 반환하고, WSA_IO_PENDING 이라는 에러코드를 발생할 것입니다. 이러한 경우에 lpNumberOfBytesSent 매개변수는 전송된 값을 포인트 하지 않습니다. 오버랩 연산이 완료되었을 때, 전송된 데이터의 수치는 완료루틴의 cbTransferred 매개변수나 WSAGetOverlappedResult 함수의 lpcbTransfer 매개변수를 가지고 알 수 있습니다.

WSASend 함수는 이전에 호출한 WSARecv, WSARecvFrom, WSASend, WSASendTo 함수들의 완료함수 내부에서 호출될 수 있습니다.

만약 여러개의 I/O 연산이 동시에 일어난 다면, 각각의 연산은 서로다른 WSAOVERLAPPED 구조체를 참조해야 합니다.

lpCompletionRoutine 매개변수가 NULL이라면, lpOverlapped 매개변수의 hEvent 필드는 오버랩 연산이 완료 되었을 때 신호를 받게 됩니다. 어플레케이션은 WSAWaitForMultipleEventsWSAGetOverlappedResult 함수를 사용해서 이벤트 객체에 대해서 대기하거나 폴링할 수 있습니다.

lpCompletionRoutine 매개변수가 NULL이 아니 이라면, hEvent 필드는 무시되고, 완료루틴을 위한 흐름정보(context information)를 사용할 수 있게 됩니다. 이렇게 NULL 이 아닌 lpCompletionRoutine 을 넘겨주는 콜러와 나중에 같은 오버랩 I/O 요청을 위해 호출되는 WSAGetOverlappedResult 함수는 WSAGetOverlappedResult 함수를 TRUE로 호출하기위한 fWait 맵개변수를 셋팅하지 않습니다. 이러한 경우에 hEvent 필드를 사용하는 특별한 방법은 정의되지 않습니다. 그리고, hEvent 필드를 사용해 대기하려 하면, 예측할 수 없는 결과를 가져 올 수도 있습니다.

완료루틴은 Win32 파일 I/O 완료루틴과 같은 규칙을 따르게 됩니다. 완료루틴은 WSAWaitForMultipleEvents 함수가 fAlertable 매개변수를 TRUE로 설정하여 호출될 때와 같이 작업쓰레드가 반응할수있는(alertable) 대기 상태에 있을 때 까지 호출되지 않을 것입니다.

완료루틴의 프로토타입은 아래와 같습니다.

void CALLBACK CompletionROUTINE(
        IN DWORD  
dwError,
        IN DWORD  
cbTransferred,
        IN LPWSAOVERLAPPED  
lpOverlapped,
        IN DWORD  
dwFlags
);

CompletionRoutine 함수는 어플리케이션-정의 또는 라이브러리 정의 함수 이름으로 사용됩니다. dwError 매개변수는 lpOverlapped 에 의해서 표현되는 오버랩 연산에 대한 완료의 상태를 가리킵니다. cbTransferred 매개변수는 전송한 데이터의 바이트 수를 나타냅니다. 일반적으로 dwFlags 매개변수는 잘 사용되지 않습니다. 이값은 0 값을 가지게 될 것입니다. 이 함수는 반환값이 없습니다.

 

Return Values

에러가 발생하지 않고, 전송연산이 바로 완료되었다면, WSASend 함수는 0을 반환 합니다. 이러한 경우에 완료루틴은 호출쓰레드가 반응할 수 있는(alertable) 상태로 호출되기 위한 준비를 이미 같추었다고 볼 수 있습니다. 에러가 발생한 경우 SOCKET_ERROR 값이 반환 됩니다. 그리고, WSAGetLastError 함수를 호출해 특정한 에러코드를 얻어낼 수 있습니다.

 

Error Codes

WSANOTINITIALISED

이 함수를 사용하기 이전에 WSAStartup 함수를 성공적으로 호출해야 합니다.

WSAENETDOWN

네트웍 서브 시스템에 에러가 발생했습니다.

WSAEACCES 지정된 어드레스는 브로드캐스팅 어드레스 인데, 적절한 플래그가 사용되지 않았습니다.
WSAEINTR 블럭킹 윈속 v1.1 이 WSACancelBlockingCall 함수에서 취소되었습니다
WSAEINPROGRESS

블럭킹 윈속 v1.1 이 현재 진행 중입니다.

WSAEFAULT lpBuffers, lpNumberOfBytesSent, lpOverlapped, lpCompletionRoutine 매개변수가 올바른 어드레스를 넘기지 않았습니다.
WSAENETRESET 작업이 진행되고 있는 도중에 에러상황이 검출되어서 접속이 해제 되었습니다.
WSAENOBUFS 버퍼 사용중 데드락에 걸렸습니다.
WSAENOTCONN 지정된 소켓이 접속된 소켓이 아닙니다.
WSAENOTSOCK 지정한 소켓 기술자가 소켓기술자가 아닙니다.
WSAEOPNOTSUPP MSG_OOB 플래그가 지정되었으나, 소켓이 SOCK_STREAM 과 같은 타입의 스트림 형태의 소켓이 아닌 경우 이거나, 소켓이 out-of-band 데이터를 지원하지 않는 형태의 소켓입니다. 그리고, MSG_PARTIAL 형태가 지원되지 않거나, 소켓이 단방향 이어서 데이터 수신 연산만을 지원하는 형태입니다.
WSAESHUTDOWN 소켓이 셧다운 되었습니다. 소켓에 대해서 shutdown 함수를 호출한 후에는 WSASend 함수를 사용할 수 없습니다.
WSAEWOULDBLOCK 오버랩 소켓      : 너무많은 오버랩 I/O가 발생했습니다.
넌-오버랩 소켓 : 소켓이 비동기 소켓일 경우 전송 연산이 바로 완료될 수 없습니다. ( 언젠가는 완료가 될 것이므로 확실한 에러상황이라고 볼 수 없죠.)
WSAEMSGSIZE 소켓이 메시지지향 소켓(SOCK_DGRAM)일때, 전송하려는 데이터의 크기가 지원되는 최대 크기보다 더 큽니다.
WSAEINVAL 소켓이 bind 함수로 바인드 되지 않았거나, 소켓이 오버랩 플래그를 사용해서 생성되지 않았습니다.
WSAECONNABORTED 가상 연결망이 타임아웃이나 그외 다른 에러상황으로 끊겨 버렸습니다.
WSAECONNRESET 가상 연결망이 상대방에 의해서 리셋되었습니다.
WSA_IO_PENDING 오버랩 연산이 성공적으로 시작되었고, 작업이 잠시 후에 완료될 예정입니다.
WSA_OPERATION_ABORTED 오버랩 연산이 소켓의 닫힘 때문에 취소되었거나, SO_FLUSH 컴맨드로 WSAIoctl 함수를 수행해서 연산이 도중에 취소 되었습니다.

 

QuickInfo

Windows NT : 사용가능
Windows : 사용가능
Windows CE : 지원되지 않음
Header :
          Win16/32 : winsock.h
          Win32-II : winsock2.h
Import Library :
          Win16 : winsock.lib
          Win32 : wsock32.lib
          Win32-II : ws2_32.lib

See Also

overview, WSACloseEvent, WSACreateEvent, WSAGetOverlappedResult, WSASocket, WSAWaitForMultipleEvents

반응형

+ Recent posts