-------------------------------------------------------------------------------------------------
참조: TCP/IP 소켓 프로그래밍
-------------------------------------------------------------------------------------------------
1. 조건부 억셉트
: 클라이언트의 접속 허용 여부를 설정할 수 있다.
1) SOCKET WSAAccept (
SOCKET s, ... ①
struct sockaddr FAR *addr, ... ②
LPINT addrlen, ... ③
LPCONDITIONPROC lpfnCondition, ... ④
DWORD dwCallBackData ... ⑤
);
① Listen Socket Handle
② Accept 될 상대편 주소의 구조체
③ ② 구조체의 길이
④ 조건부 Accept 함수 포인터
⑤ 조건부 Accept 함수가 호출될 때 사용
: 조건부 Accept 함수에서 CF_ACCEPT를 리턴 시키면 클라이언트로부터 접속을 받아들이고,
CF_REJECT를 리턴하게 되면 해당 접속은 거절되어 무시되고, WSAECONNREFUSED 오류 코드를
발생시킨다.
: WSAAccept() 함수는 동작시키는 스레드가 실행하기 때문에 빨리 실행하고 리턴해야 한다.
따라서 일단 CF_DEFFER를 리턴해서 나중에 접속을 받아들일지 거절할 것인지를 알려주겠다고
하면 된다. (이 경우 일단 Accept 동작은 무시하게 되고 접속 허용 여부를 다시 결정한다.)
: 블로킹 모드 - 접속 대기 큐가 비었다면, accept와 마찬가지로 블로킹 되어 멈춰있다.
비블로킹 모드 - 접속 대기 큐가 비었다면, WSAEWOULDBLOCK 오류를 리턴한다.
2) CONDITIONPROC 함수 (④)
- int CALLBACK ConditionFunc (
IN LPWSABUF lpCallerId, ... ①
IN LPWSABUF lpCallerData, ... ②
IN OUT LPQOS lpSQOS, ... ③
IN OUT LPQOS lpGQOS, ... ④
IN LPWSABUF lpCalleeId, ... ⑤
OUT LPWSABUF lpCalleeData, ... ⑥
OUT GROUP FAR *g, ... ⑦
IN DWORD dwCallbackData ... ⑧
);
① WSABUF의 포인터. WSABUF 구조체 안의 멤버 자료 buf에 SOCKADDR 구조체를 담고 있어
접속을 시도한 클라이언트의 주소 정보를 얻어낼 수 있다.
② 연결 시점에서 받은 데이터가 있다면 WSABUF의 포인터로 들어온다.
③ references the FLOWSPEC structures for socket s specified by the caller,
one for each direction, followed by any additional provider-specific parameters.
④ The lpGQOS parameter is reserved, and should be NULL.
⑤ 서버 자기 자신의 주소에 대한 정보가 담겨있다. ①과 마찬가지로 데이터를 얻을 수 있다.
⑥ 접속 시점에서 클라이언트로 보낼 데이터를 설정하는 인자.
TCP에서는 이미 조건부 함수가 호출되기 전에 클라이언트의 접속이 완료되므로 의미가 없다.
⑦ Socket Group
⑧ WSAAccept 함수를 호출할 때 마지막에 넣었던 콜백 데이터. (추가적인 자료)
3) WSABUF 구조체: 버퍼 정보를 담기 위한 구조체
typedef struct __WSABUF
{
u_long len; // 버퍼 사이즈
char FAR *buf; // 버퍼 시작 주소
} WSABUF, FAR *LPWSABUF;
2. scatter/gather I/O
: Winsock2에서는 WSASend() 함수나 WSASendTo() 함수 그리고 WSARecv() 함수나 WSARecvFrom()
함수에서 보내거나 받기 위한 버퍼를 배열로 인자를 넣을 수 있는데 이를 scatter/gather I/O 또는
vectored I/O 라고 한다.
: 분리된 버퍼들에 차례로 데이터를 받게 할 수 있는 기법으로, 분리된 버퍼들을 한 곳에 복사하는
임시 버퍼를 사용하지 않고, 한 번에 보내고 받을 수 있어 네트워크 성능 향상을 꾀할 수 있다.
1) int WSASend (
SOCKET s, ... ①
LPWSABUF lpBuffers, ... ②
DWORD dwBufferCount, ... ③
LPDWORD lpNumberOfBytesSent, ... ④
DWORD dwFlags, ... ⑤
LPWSAOVERLAPPED lpOverlapped, ... ⑥
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE ... ⑦
);
① 접속된 소켓을 가리키는 소켓 기술자.
② WSABUF 구조체의 포인터.
③ lpBuffer 배열로 지정된 WSABUF 구조체의 갯수.
④ 이 함수의 호출로 인해서 전송된 바이트의 개수를 포인트 합니다.
(한 번의 호출로 보내진 양을 나타낸다.)
⑤ 어떠한 방식으로 전송을 수행 할 것인지 설정하는 플래그.
<Overlapped 이벤트로 시그널을 받을 것인지, 완료 루틴(⑦)으로 나중에 호출할 것인지를 결정>
⑥ WSAOVERLAPPED 구조체의 포인터. (Non-Overlapped 소켓에 대해서는 무시됩니다.)
⑦ 전송연산이 완료되었을 때 호출되는 전송완료 루틴에 대한 포인터입니다.
(Non-Overlapped 소켓에 대해서는 무시됩니다.)
2) int WSARecv (
SOCKET s, ... ①
LPWSABUF lpBuffers, ... ②
DWORD dwBufferCount, ... ③
LPDWORD lpNumberOfBytesRecvd, ... ④
LPDWORD lpFlags, ... ⑤
LPWSAOVERLAPPED lpOverlapped, ... ⑥
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE ... ⑦
);
① 접속된 소켓의 기술자.
② WSABUF 구조체의 배열 포인터로, 각각의 WSABUF 구조체는 데이터를 담은 버퍼와 버퍼의 길이를
가지게 됩니다.
③ lpBuffer 배열에 있는 WSABUF 구조체( 배열의 엘리먼트)의 개수
④ 데이터 수신 작업이 바로 완료된 경우, 이 함수의 호출로 읽어낸 데이터의 바이트 수를 포인트 합니다.
(한 번의 호출로 보내진 양을 나타낸다.)
⑤ 어떠한 방식으로 이 함수를 호출할 것인가를 나타내는 플래그.
<Overlapped 이벤트로 시그널을 받을 것인지, 완료 루틴(⑦)으로 나중에 호출할 것인지를 결정>
⑥ WSAOVERLAPPED 구조체의 포인터. (Non-Overlapped 소켓에 대해서는 무시됩니다.)
⑦ 수신 작업이 완료되었을 때 호출될 완료 루틴의 포인터.
(Non-Overlapped 소켓에 대해서는 무시됩니다.)
3) 사용 예 (WSASend())
char *pHeader; char *pHeader;
char *pContents; char *pContents;
... → ...
char buf[100]; WSABUF wbuf[2];
memcpy(buf, pHeader, 10); wbuf[0].buf = pHeader;
memcpy(buf, pContents, 30); wbuf[0].len = 10;
wbuf[1].buf = pContents;
send(s, buf, 40, 0); wbuf[1].len = 30;
DWORD dwSent;
WSASend(s, wbuf, 2, &dwSent, 0, NULL, NULL);
: 일일이 분리된 버퍼에 나누어 복사할 필요 없이 바로 각 버퍼에 담을 수 있다.
char *pHeader = new char[10];
char *pContents = new char[30];
...
WSABUF wbuf[2];
wbuf[0].buf = pHeader;
wbuf[0].len = 10;
wbuf[1].buf = pContents;
wbuf[1].len = 30;
DWORD dwRead;
WSARecv(s, wbuf, 2, &dwRead, 0, NULL, NULL);
-------------------------------------------------------------------------------------------------
'IT_Programming > Network Programming' 카테고리의 다른 글
[펌] 소켓 입출력 모델 - WSAAsyncSelect 모델 (0) | 2009.11.18 |
---|---|
Raw Socket (0) | 2009.11.13 |
성능 향상을 위한 소켓 제어 (0) | 2009.11.12 |
[펌] fork()를 이용한 다중연결 서버 구현 (0) | 2009.10.31 |
[I/O Multiplexing] select를 이용한 멀티플렉싱 구현 (Ver. Win / Linux) (0) | 2009.07.07 |