|
| |
|
|
|
 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| | |
|
| http://gustmder.tistory.com/trackback/101
| |
|
| |
| | |
|
|
|
| |
|
TCP / IP | 2009/06/01 13:43
|
 |
|
|
| - #include <iostream>
- #include <winsock2.h>
- #pragma comment(lib, "ws2_32.lib")
- using namespace std;
- const int MAX_LEN = 100;
- typedef struct
- {
- SOCKET hClntSock;
- SOCKADDR_IN clntAddr;
- }PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
- typedef struct
- {
- OVERLAPPED overlapped;
- char buffer[MAX_LEN];
- WSABUF wsaBuf;
- }PER_IO_DATA, *LPPER_IO_DATA;
- DWORD WINAPI CompletionThread(LPVOID ComplectionPortIO);
- void ErrorHandling(char * msg);
- int main(void)
- {
- WSADATA wsaData;
- HANDLE hCompletionPort;
- SYSTEM_INFO SystemInfo;
- SOCKADDR_IN servAddr;
- LPPER_IO_DATA PerIoData;
- LPPER_HANDLE_DATA PerHandleData;
- SOCKET hServSock;
- unsigned long RecvBytes;
- unsigned long i, Flags;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- ErrorHandling("윈속초기화에러");
- //1. Completion Port 생성
- hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL,0, 0);
- GetSystemInfo(&SystemInfo);
- //2. 쓰레드를 CPU 개수만큼 생성.
- for (i = 0; i < SystemInfo.dwNumberOfProcessors; i++)
- CreateThread(NULL, 0, CompletionThread, (LPVOID)hCompletionPort, 0, NULL);
- hServSock = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
- servAddr.sin_family = AF_INET;
- servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- servAddr.sin_port = htons((u_short)atoi("9999"));
- bind(hServSock, (SOCKADDR * )&servAddr, sizeof(servAddr));
- listen(hServSock, 5);
- while (true)
- {
- SOCKET hClntSock;
- SOCKADDR_IN clntAddr;
- int addrLen = sizeof(clntAddr);
- hClntSock = accept(hServSock, (SOCKADDR *)&clntAddr, &addrLen);
- // 연결된 클라이언트의 소켓 핸들 정보와 주소 정보를 설정.
- PerHandleData =
- (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
- PerHandleData->hClntSock = hClntSock;
- memcpy(&(PerHandleData->clntAddr), &clntAddr, addrLen);
-
- //3. Overlapped 소켓과 CompletionPort의 연결.
- CreateIoCompletionPort((HANDLE)hClntSock, hCompletionPort, (DWORD)PerHandleData, 0);
- //클라이언트를 위한 버퍼를 설정, OVERLAPPED 변수 초기화
- PerIoData = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
- memset(&(PerIoData->overlapped), 0, sizeof(OVERLAPPED));
- PerIoData->wsaBuf.len = MAX_LEN;
- PerIoData->wsaBuf.buf = PerIoData->buffer;
- Flags = 0;
- //4. 중첨된 데이터 입력.
- WSARecv(PerHandleData->hClntSock, // 데이터 입력소켓.
&(PerIoData->wsaBuf), //데이터 입력 버퍼 포인터. 1, //데이터 입력버퍼의 수. &RecvBytes, &Flags, &(PerIoData->overlapped), //OVERLAPPED 변수 포인터. NULL);
- }
- return 0;
- }
- DWORD WINAPI CompletionThread(LPVOID pComPort)
- {
- HANDLE hCompletionPort = (HANDLE)pComPort;
- DWORD BytesTransferred;
- LPPER_HANDLE_DATA PerHandleData;
- LPPER_IO_DATA PerIoData;
- DWORD Flags;
- while (true)
- {
- //5. 입. 출력이 완료된 소켓의 정보를 얻음.
- GetQueuedCompletionStatus(hCompletionPort, //Completion Port
&BytesTransferred, //전송된 바이트수. (LPDWORD)&PerHandleData, (LPOVERLAPPED *)&PerIoData, INFINITE);
- if (BytesTransferred == 0) // EOF전송시
- {
- closesocket(PerHandleData->hClntSock);
- free(PerHandleData);
- free(PerIoData);
- continue;
- }
- //6. 메시지! 클라이언트로 에코.
- PerIoData->wsaBuf.len = BytesTransferred;
- WSASend(PerHandleData->hClntSock, &(PerIoData->wsaBuf), 1, NULL, 0, NULL, NULL);
- //Receive Again
- memset(&(PerIoData->overlapped), 0, sizeof(OVERLAPPED));
- PerIoData->wsaBuf.len = MAX_LEN;
- PerIoData->wsaBuf.buf = PerIoData->buffer;
- Flags = 0;
-
WSARecv(PerHandleData->hClntSock, &(PerIoData->wsaBuf),
1, NULL, &Flags, &(PerIoData->overlapped), NULL);
- }
- return 0;
- }
- void ErrorHandling(char * msg)
- {
- fputs(msg, stderr);
- fputc('\n', stderr);
- exit(1);
- }
| |
|
|
|
|
|
|
|
|
|
|
| | |
|
| http://gustmder.tistory.com/trackback/96
| |
|
| |
| | |
|
|
|
| |
| |
| | |
|
«
2012/02
»
| 일 |
월 |
화 |
수 |
목 |
금 |
토 |
| |
|
|
1 |
2 |
3 |
4 |
| 5 |
6 |
7 |
8 |
9 |
10 |
11 |
| 12 |
13 |
14 |
15 |
16 |
17 |
18 |
| 19 |
20 |
21 |
22 |
23 |
24 |
25 |
| 26 |
27 |
28 |
29 |
|
|
|
| |
| | |
|
|
|
|
|
| | |
|
슈퍼맨 2011
한남자@ 2009
선화 2009
Namz 2009
선화 2009
페르제브 2008
선화 2008
R 2008
| |
| | |
|
|
|
|
|
|
|
|