Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

WSASend

연결 소켓(:12)으로 데이터를 전송한다.
int WSASend(
  __in   SOCKET s,
  __in   LPWSABUF lpBuffers,
  __in   DWORD dwBufferCount,
  __out  LPDWORD lpNumberOfBytesSent,
  __in   DWORD dwFlags,
  __in   LPWSAOVERLAPPED lpOverlapped,
  __in   LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

매개 변수

  • s
연결 소켓을 가리키는 소켓 지정 번호
  • lpBuffers
WSABUF(:4300)구조체 배열의 포인터로 각각의 WSABUF 구조체는 버퍼와 버퍼의 크기를 가리킨다.
  • dwBufferCount
lpBuffers에 있는 WSABUF(:4300)구조체의 개수
  • lpNumberOfBytesSent
함수의 호출로 전송된 데이터의 바이트 크기를 념겨준다. 만약 매개 변수 lpOverlapped가 NULL이 아니라면, 이 매개 변수의 값은 NULL로 해야 한다. 그래야 (잠재적인)잘못된 반환을 피할 수 있다.
  • dwFlags
WSASend 함수를 어떤 방식으로 호출 할것인지를 지정한다.
  • lpOverlapped
WSAOVERLAPPED(:4300)구조체의 포인터다. 비 (overlapped)중첩 소켓에서는 무시된다.
  • lpCompletionRoutine
데이터 전송이 완료 되었을 때 호출할 완료 루틴 (completion routine)의 포인터. 비 중첩 소켓에서는 무시 된다.

반환 값

데이터 전송을 완료했다면 0을 반환한다. 이 경우 완료 루틴은 호출 쓰레드가 반응할 수 있는 상태로 호출하기 위한 준비를 갖추었다고 볼 수 있다. 실패할 경우 SOCKET_ERROR를 반환한다. 에러 코드는 WSAGetLastError(:4100) 함수로 가져올 수 있다. 에러 코드가 WSA_IO_PENDING이면 중첩 연산을 위한 초기화 작업이 성공적으로 진행 되었으며, 완료에 대한 측정은 나중에 이루어질 것임을 의미한다.

에러 코드 에러 값 설명
WSAECONNABORTED 10053 타임아웃 혹은 상대방의 접속종료들과 같은 소프트웨어적인 문제로 연결이 끊겼음.
WSAEFAULT 10014 잘못된 주소를 사용했음
WSAECONNRESET 10054 연결이 원격 호스트에 의해 재설정되었음.
WSAEINTR 10004 WSACancelBlockingCall()에 의해 블록화 호출이 취소: Interrupted system call
WSAEINPROGRESS 10036 블록화 함수가 진행되는 동안 부적절한 윈속 API함수가 호출.
WSAEINVAL 10022 바인딩 실패. 이미 bind된 소켓에 바인드하거나 주소체계가 일관적이지 않을 때
WSAEMSGSIZE 10040 송수신에 사용된 데이터가 버퍼의 크기를 초과해서 크기에 맞게 잘렸음
WSAENETDOWN 10050 네트워크 서브 시스템에 문제가 있음. 네트워크 접속 끊김등.
WSAENETRESET 10052 네트워크 재설정으로 연결이 끊어졌음.
WSAENOBUFS 10055 남아있는 버퍼공간이 없어서 소켓을 사용할 수 없음
WSAENOTCONN 10057 연결되지 않은 소켓임. 연결되지 않은 소켓에 읽고 쓰는 경우
WSAENOTSOCK 10038 잘못된 소켓기술자를 사용했음
WSAEOPNOTSUPP 10045 소켓이 지원하지 않는 명령을 사용했음. listen()함수를 데이터그램 통신 (SO_DGRAM)에서 호출
WSAESHUTDOWN 10058 소켓이 종료되었음. 종료된 소켓에 데이터를 읽고 쓰려 경우
WSAEWOULDBLOCK 10035 비봉쇄모드에 있는 소켓에 봉쇄 명력을 요청
WSANOTINITIALISED 10093 WSAStartup() 함수가 성공적으로 실행되지 않은 상황에서 윈속 함수를 호출했을 때
WSA_IO_PENDING 997 Overlapped 연산은 나중에 완료될 것이다. 중첩 연산을 위한 준비가 되었으나, 즉시 완료되지 않았을 경우발생
WSA_OPERATION_ABORTED 995 overlapped(:12) 연산이 중단 되었다.

설명

WSASend 함수는 send(:4100)함수의 확장 함수로 send의 기능을 모두 지원하며, 아래의 기능이 추가되어 있다.
  1. 중첩 연산을 할 수 있다.
  2. 여러 개의 전송 버퍼를 전송할 수 있다.
WSASend 함수는 연결 지향 소켓에서 하나 이상의 데이터 버퍼를 전송하기 위해 사용하는 함수다. 이 함수를 비 연결 지향 소켓에서 사용하기 위해서는 connect(:4100)나 WSAConnect(:4100) 함수로 상대방 인터넷(:12)주소 정보가 바인딩 되어 있어야 한다.

socket 함수로 만들어진 소켓은 기본적으로 중첩 특성을 가지고 있다. WSASocket 함수로 소켓을 만든다면 WSA_FLAG_OVERLAPPED비트를 설정해야 한다. 소켓이 중첩 특성을 가지면 WSASend는 중첩 입출력 연산을 수행한다. 만약 이때 lpOverlapped 와 lpCompletionRoutine가 NULL 이라면 중첩 입출력은 무시되고 send(:4100)함수와 동일하게 작동한다.

비 중첩 소켓에서 lpOverlapped와 lpCompletionRoutine는 무시되며 봉쇄 send(:4100)함수와 동일하게 작동한다.

dwFlags의 사용

dwFlags는 소켓의 작동 방식을 결정하기 위해서 사용한다.
MSG_DONTROUTE 라우팅 정보를 쓰지 않는다. 로컬 네트워크 통신만을 하겠다는 의미지만, 윈도 소켓은 이 값을 무시한다.
MSG_OOB OOB(긴급 데이터)를 전송한다. 단지 연결 지향 소켓 (SOCK_STREAM)에서만 사용할 수 있다.
MSG_PARTIAL lpbuffers 매개 변수가 부분적인 메시지만 담도록 한다.

중첩 입출력

만약 중첩 연산이 바로 완료되면 WSASend 함수는 0을 반환하고 전송한 데이터의 바이트 크기를 lpNumberOfBytesSend 값으로 설정한다. 만약 중첩 연산이 성공적으로 초기화 되고 아직 완료되지 않았다면, WSASend는 SOCKET_ERROR를 반환한다. 중첩 연산이 나중에 이루어질 것이라는 것은 WSA_IO_PENDING에러 코드로 확인할 수 있다. 이 경우 lpNumberOfBytesSend 값은 수정되지 않는다.

WSASend 함수는 이전에 호출한 WSARecv(:4100), WSARecvFrom(:4100), WSASend(:4100), WSASendTo(:4100)함수의 완료 함수에서 호출할 수 있다.

만약 여러 개의 입출력이 동시에 일어난 다면, 각각의 연산은 서로 다른 WSAOVERLAPPED 구조체를 참조해야 한다.

완료 루틴은 윈도 파일 입출력의 완료 루틴과 같은 규칙을 따른다. 완료 루틴은 스레드가 alertable 상태가 되지 않을 때까지 대기하게 된다.

완료 루틴의 프로토 타입은 다음과 같다.
void CALLBACK CompletionROUTINE(
  IN DWORD dwError,
  IN DWORD cbTransferred,
  IN LPWSAOVERLAPPED lpOverlapped,
  IN DWORD dwFlags
);

예제