ÃÑ ÆäÀÌÁö ¼ö : 3224
![]()
|
Facebook Joinc ±×·ì
Joinc QA »çÀÌÆ®
![]()
Tweet
joinc´Â Firefox¿Í chrome¿¡¼ Å×½ºÆ® Çß½À´Ï´Ù. IE¿¡¼´Â Å×À̺íÀÌ ±úÁö°Å³ª À̹ÌÁö°¡ º¸ÀÌÁö ¾ÊÀ» ¼ö ÀÖ½À´Ï´Ù. ƯÈ÷ ±¸±Û DocsÀ̹ÌÁöÀÇ °æ¿ì ¿¢¹Úó¸®µÉ ¼ö ÀÖ½À´Ï´Ù. 1 Overlapped I/O ¸ðµ¨
¼ÒÄÏÀº ±âº»ÀûÀ¸·Î ºÀ¼â/µ¿±â·Î ¸¸µé¾îÁø´Ù. ÀÌ ¸ðµ¨Àº µ¥ÀÌÅÍ ÀÔÃâ·Â ºÎºÐ¿¡¼ ºÀ¼â(blocked)µÈ´Ù´Â ¹®Á¦Á¡À» °¡Áø´Ù.
ÀÌ ¸ðµ¨·Î´Â ÇϳªÀÇ ¾²·¹µå¿¡¼ µÎ °³ ÀÌ»óÀÇ ¼ÒÄÏÀ» ´Ù·ç±â°¡ Èûµé´Ù. ÀÌ ¸ðµ¨À» ¹Ù²ÙÁö ¾Ê°í µÎ°³ ÀÌ»óÀÇ ¼ÒÄÏÀ» ó¸®ÇÏ·Á¸é "¸ÖƼ ¾²·¹µå" ±â¼úÀ» ÇÔ²² »ç¿ëÇÏ´Â ¼ö ¹Û¿¡ ¾ø´Ù.
À©µµ ¿î¿µÃ¼Á¦´Â ¸ÖƼ ŽºÅ·À» Áö¿øÇÑ´Ù. ÀÌ´Â ÀÔÃâ·Â ¸ðµ¨°ú´Â »ó°ü¾øÀÌ, Ä¿³ÎÀº ¿©·¯ ¼ÒÄÏÀ¸·Î ºÎÅÍÀÇ ÀÔ·ÂÀ» ó¸®ÇÑ´Ù´Â Àǹ̴Ù. À̱â´ÉÀ» ºÀ¼â/µ¿±â ÀÔÃâ·Â ¸ðµ¨ÀÇ ÇѰè·Î ¾²Áö ¸øÇÏ´Â °ÍÀÏ »ÓÀÌ´Ù.
ÀÌ ¹®Á¦´Â ÀÔÃâ·Â ¸ðµ¨À» "ºñµ¿±â / ºÀ¼â" ȤÀº "ºñµ¿±â / ºñºÀ¼â"À» ¾²´Â °ÍÀ¸·Î ÇØ°áÇÒ ¼ö ÀÖ´Ù. ºñµ¿±â ºÀ¼â ¸ðµ¨À» »ç¿ëÇÏ´Â ±â¼úÀÌ selectÇÔ¼ö¸¦ ÀÌ¿ëÇÑ ÀÔÃâ·Â ´ÙÁßÈÀÌ´Ù. Overlapped I/O ¸ðµ¨Àº "ºñµ¿±â / ºñºÀ¼â ¸ðµ¨"ÀÇ ÀÀ¿ë ¸ðµ¨ÀÌ´Ù. Overlapped¿¡´Â non-blockingÀÌ Æ÷ÇԵǾî ÀÖ´Ù. Áï Overlapped ´Â non-block + (ºñµ¿±âÀû) ¿Ï·á Å뺸 ¶ó°í º¸¸é µÈ´Ù.
Overlapped I/O´Â ´ÙÀ½°ú °°ÀÌ ¹¦»çÇÒ ¼ö ÀÖ´Ù. (Á¤È®ÇÑ ¹¦»ê´Â ¾Æ´Ï´Ù.)
¾Õ¼ ¾ð±ÞÇßµíÀÌ Ä¿³ÎÀº ¿©·¯ °³ÀÇ ¼ÒÄÏÀÇ µ¥ÀÌÅ͸¦ µ¿½Ã¿¡ ´Ù·ê ¼ö ÀÖ´Ù. ±×·¯´Ù º¸¸é ½Ã°£À» ÃàÀ¸·Î µ¥ÀÌÅͰ¡ ÁßøÀÌ µÇ´Â ±¸°£ÀÌ »ý±æ ¼öµµ ÀÖÀ» °ÍÀÌ´Ù. ÀÌÁ¦ µ¥ÀÌÅÍÀÇ ÀÔ·ÂÀÌ ¿Ï·áµÇ¸é, ÇØ´ç ¼ÒÄÏ¿¡¼ À̺¥Æ®¸¦ ÅëÁöÇÑ´Ù. À̺¥Æ®¸¦ ¹ÞÀº ÇÁ·Î¼¼½º´Â À̺¥Æ® °´Ã¼¸¦ ÀÌ¿ëÇØ¼ µ¥ÀÌÅ͸¦ ó¸®Çϰųª ȤÀº Completion Routine¸¦ ÀÌ¿ëÇØ¼ µ¥ÀÌÅ͸¦ ó¸®ÇÒ ¼ö ÀÖ´Ù. ÁßÃ¸ÇØ¼ µé¾î¿Ã ¼ö ÀÖ´Â µ¥ÀÌÅÍÀÇ Ã³¸®¸¦ Ä¿³Î¿¡ ¸Ã±â°Ô µÇ¹Ç·Î À¯Àú ¸ðµå¿¡¼ ºí·°µÇ´Â ÀÏ ¾øÀÌ ¿©·¯ °³ÀÇ ¼ÒÄÏÀ» ó¸®ÇÒ ¼ö ÀÖ´Ù.
Overlapped I/OÀÇ ÁßøÀ» Çã¿ëÇÏ´Â ÀÌ·± Ư¡ ¶§¹®¿¡, "Áßø ÀÔÃâ·Â ¸ðµ¨"À̶ó°í ºÎ¸£±âµµ ÇÑ´Ù. »ý¼ÒÇÑ ±â¼ú °°Áö¸¸, ¿ø¸®¿¡ À־ ¸®´ª½ºÀÇ ÀÔÃâ·Â ´ÙÁßȳª ¸®¾ó ŸÀÓ ½Ã±×³Î°ú Å« Â÷À̰¡ ¾øÀ½À» ¾Ë ¼ö ÀÖ´Ù. ´ÙÀ½Àº ºñ µ¿±â / ºñ ºÀ¼â ÀÔÃâ·Â¸ðµ¨À» µû¸£´Â ÇÁ·Î±×·¥ÀÇ È帧À» º¸¿©ÁØ´Ù.
À©µµÀÇ Overlapped I/O¸ðµ¨Àº µ¥ÀÌÅÍ ÀÔÃâ·ÂÀÌ ¿Ï·áµÈ ½ÃÁ¡¿¡¼ À̺¥Æ®¸¦ ¹ß»ýÇÑ´Ù. ÀÌ·Î ÀÎÇØ ¾òÀ» ¼ö ÀÖ´Â ÀÌÁ¡Àº ´ÙÀ½°ú °°´Ù.
1.1 Overlapped ¼ÒÄÏ ÇÁ·Î±×·¥
socket ÇÔ¼ö·Î ¸¸µç ¼ÒÄÏÀº ±âº»ÀûÀ¸·Î Áßø Ư¼ºÀ» °¡Áø´Ù. ±×·¯³ª ´Ù¸¥ BSD ¼ÒÄÏÀÔÃâ·Â ÇÔ¼öµé·Î´Â Áßø ¼ÒÄÏÀ» ´Ù·çÁö ¸øÇÑ´Ù. ±×·¯¹Ç·Î BSD ¼ÒÄÏ ÀÔÃâ·Â ÇÔ¼ö´ë½Å WSASend, WSARecv, WSASendTo, WSARecvFrom µîÀÇ ÇÔ¼ö¸¦ ÀÌ¿ëÇØ¾ß ÇÑ´Ù. WSASocket ÇÔ¼ö·Î ¼ÒÄÏÀ» ¸¸µé °æ¿ì¿¡´Â WSA_FLAG_OVERLAPPED¸¦ ÁöÁ¤ÇØÁà¾ß ÇÑ´Ù.
Áßø ¼ÒÄÏÀ» »ç¿ëÀº WSAsend ÇÔ¼öÀÇ lpOverlapped ¸Å°³ º¯¼ö¿Í lpCompletionRoutine ¸Å°³ º¯¼ö·Î ÀÌ·ç¾îÁø´Ù.
1.1.1 À̺¥Æ® °´Ã¼ ±â¹Ý ó¸®
lpCompletionRoutineÀÌ NULLÀÏ °æ¿ì, WSAOVERLAPPED ±¸Á¶Ã¼ÀÇ À̺¥Æ® °´Ã¼ Çڵ鷯·Î ÀÔ·ÂÀ» ó¸®ÇÑ´Ù. À̶§ acceptÇÔ¼ö¸¦ ¾î¶»°Ô ó¸®ÇØ¾ß ÇÒ °ÍÀ̳« ÇÏ´Â ¹®Á¦°¡ ÀÖ´Ù. accept ÇÔ¼ö´Â Áßø ¼ÒÄÏ Æ¯¼ºÀ» ÀÌ¿ëÇÏÁö ¸øÇÑ´Ù. ¶ÇÇÑ WSAAccept ÇÔ¼öµµ Áßø ¼ÒÄÏ Æ¯¼ºÀ» ÀÌ¿ëÇÏÁö ¸øÇÑ´Ù. accept´Â ´Ü 1 ¹ÙÀÌÆ®¸¸ µé¾î¿Íµµ ¿äûÀÌ ¿Ï·áµÇ¹Ç·Î, ±»ÀÌ Áßø Ư¼ºÀ» ÀÌ¿ëÇÒ Çʿ䰡 ¾ø±â ¶§¹®ÀÌ´Ù. acceptEx ÇÔ¼ö°¡ ÀÖ±â´Â ÇÏÁö¸¸, ±×´ÙÁö ¾²°í ½ÍÁö ¾Ê´Ù.
´ÙÀ½ µÎ °¡Áö ¹æ¹ý Áß Çϳª¸¦ ¼±ÅÃÇÏ¸é µÉ °Í °°´Ù.
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#define PORT 5150
#define DATA_BUFSIZE 8192
// ¼ÒÄÏ Á¤º¸¸¦ ÀúÀåÇϱâ À§ÇÑ ±¸Á¶Ã¼
typedef struct _SOCKET_INFORMATION {
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;
SOCKET Socket;
WSAOVERLAPPED Overlapped;
DWORD BytesSEND;
DWORD BytesRECV;
} SOCKET_INFORMATION, * LPSOCKET_INFORMATION;
// ¿¬°á ¼ÒÄÏ (inbound connection)À¸·Î ÀÔÃâ·Â 󸮸¦ À§ÇÑ ¾²·¹µå ÇÔ¼ö
DWORD WINAPI ProcessIO(LPVOID lpParameter);
DWORD EventTotal = 0;
// À̺¥Æ® ÀúÀåÀ» À§ÇÑ ±¸Á¶Ã¼ ¹è¿°ú
// ¼ÒÄÏ Á¤º¸¸¦ ÀúÀåÇϱâ À§ÇÑ ±¸Á¶Ã¼ ¹è¿
WSAEVENT EventArray[WSA_MAXIMUM_WAIT_EVENTS];
LPSOCKET_INFORMATION SocketArray[WSA_MAXIMUM_WAIT_EVENTS];
// ÀÓ°è ¿µ¿ª ¼³Á¤À» À§ÇÑ Å©¸®Æ¼Äà ¼½¼Ç °´Ã¼
// EventArray, SocketArray ¿¬»ê ¿µ¿ªÀ» ÀÓ°è ¿µ¿ªÀ¸·Î ÁöÁ¤Çϱâ À§Çؼ »ç¿ëÇÑ´Ù.
CRITICAL_SECTION CriticalSection;
int main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ListenSocket, AcceptSocket;
SOCKADDR_IN InternetAddr;
DWORD Flags;
DWORD ThreadId;
DWORD RecvBytes;
InitializeCriticalSection(&CriticalSection);
if (WSAStartup((2,2),&wsaData) != 0)
{
printf("WSAStartup() failed with error %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
else
printf("WSAStartup() looks nice!\n");
if ((ListenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Failed to get a socket %d\n", WSAGetLastError());
return 1;
}
else
printf("WSASocket() is OK lol!\n");
InternetAddr.sin_family = AF_INET;
InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
InternetAddr.sin_port = htons(PORT);
if (bind(ListenSocket, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
{
printf("bind() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("YOu see, bind() is working!\n");
if (listen(ListenSocket, 5))
{
printf("listen() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("listen() is OK maa...\n");
// Áßø ¼ÒÄÏ »ý¼º
if ((AcceptSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
{
printf("Failed to get a socket %d\n", WSAGetLastError());
return 1;
}
else
printf("WSASocket() looks OK!\n");
if ((EventArray[0] = WSACreateEvent()) == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("WSACreateEvent() is OK!\n");
// Áßø ÀÔÃâ·ÂÀ» ´Ù·ç±â À§ÇÑ ¾²·¹µå »ý¼º
if ( CreateThread(NULL, 0, ProcessIO, NULL, 0, &ThreadId) == NULL )
{
printf("CreateThread() failed with error %d\n", GetLastError());
return 1;
}
else
printf("Nothing to say, CreateThread() is OK!\n");
EventTotal = 1;
// ¸ÞÀÎ ¾²·¹µå´Â accept 󸮸¸ ´ã´çÇÑ´Ù.
while(TRUE)
{
// Ŭ¶óÀÌ¾ðÆ® ¿¬°á ¿äûÀ» °¡Á®¿Â´Ù.
if ((AcceptSocket = accept(ListenSocket, NULL, NULL)) == INVALID_SOCKET)
{
printf("accept() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("accept() is OK!\n");
// ¼º°øÀûÀ¸·Î ¿¬°á ¼ÒÄÏÀ» °¡Á®¿À¸é, À̺¥Æ® Á¤º¸ ¹è¿°ú ¼ÒÄÏ Á¤º¸ ¹è¿¿¡ Á¤º¸¸¦ Ãß°¡Çϰí
// Áßø ÀÔÃâ·Â ¿¬»êÀ» ¼öÇàÇÑ´Ù.
EnterCriticalSection(&CriticalSection);
if ((SocketArray[EventTotal] = (LPSOCKET_INFORMATION) GlobalAlloc(GPTR, sizeof(SOCKET_INFORMATION))) == NULL)
{
printf("GlobalAlloc() failed with error %d\n", GetLastError());
return 1;
}
else
printf("GlobalAlloc() for LPSOCKET_INFORMATION is pretty fine!\n");
// ¿¬°á ¼ÒÄÏ Á¤º¸¸¦ ¼ÒÄÏ Á¤º¸ ±¸Á¶Ã¼ ¹è¿¿¡ Ãß°¡ÇÑ´Ù.
SocketArray[EventTotal]->Socket = AcceptSocket;
ZeroMemory(&(SocketArray[EventTotal]->Overlapped), sizeof(OVERLAPPED));
SocketArray[EventTotal]->BytesSEND = 0;
SocketArray[EventTotal]->BytesRECV = 0;
SocketArray[EventTotal]->DataBuf.len = DATA_BUFSIZE;
SocketArray[EventTotal]->DataBuf.buf = SocketArray[EventTotal]->Buffer;
if ((SocketArray[EventTotal]->Overlapped.hEvent = EventArray[EventTotal] = WSACreateEvent()) == WSA_INVALID_EVENT)
{
printf("WSACreateEvent() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("WSACreateEvent() is OK!\n");
// WSARecv ÇÔ¼ö¸¦ È£ÃâÇØ¼ ÀÔ·Â ÀÛ¾÷ Ãʱâȸ¦ ÇÑ´Ù.
Flags = 0;
if (WSARecv(SocketArray[EventTotal]->Socket,
&(SocketArray[EventTotal]->DataBuf), 1, &RecvBytes, &Flags, &(SocketArray[EventTotal]->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return 1;
}
}
else
printf("WSARecv() should be working!\n");
EventTotal++;
LeaveCriticalSection(&CriticalSection);
// ¿öÄ¿ ¾²·¹µå¿¡ À̺¥Æ®¸¦ Çѹø º¸³»º»´Ù.
if (WSASetEvent(EventArray[0]) == FALSE)
{
printf("WSASetEvent() failed with error %d\n", WSAGetLastError());
return 1;
}
else
printf("Don't worry, WSASetEvent() is OK!\n");
}
}
DWORD WINAPI ProcessIO(LPVOID lpParameter)
{
DWORD Index;
DWORD Flags;
LPSOCKET_INFORMATION SI;
DWORD BytesTransferred;
DWORD i;
DWORD RecvBytes, SendBytes;
while(TRUE)
{
// wait ÇÔ¼ö·Î À̺¥Æ®¸¦ ±â´Ù¸°´Ù.
if ((Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE)) == WSA_WAIT_FAILED)
{
printf("WSAWaitForMultipleEvents() failed %d\n", WSAGetLastError());
return 0;
}
else
printf("WSAWaitForMultipleEvents() is OK!\n");
// 0 ¹ø À̺¥Æ® °´Ã¼¿¡¼ÀÇ À̺¥Æ®´Â µè±â ¼ÒÄÏ¿¡ °ü·ÃµÈ °ÍÀÌ´Ù.
// ¹«½ÃÇÏ°í ³Ñ¾î°£´Ù.
if ((Index - WSA_WAIT_EVENT_0) == 0)
{
WSAResetEvent(EventArray[0]);
continue;
}
SI = SocketArray[Index - WSA_WAIT_EVENT_0];
WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
// Áßø¿¬»ê °á°ú¸¦ È®ÀÎÇÑ´Ù.
// ¿¡·¯¶ó¸é ¼ÒÄÏÀ» ´Ý°í, ¼ÒÄÏ Á¤º¸ ¹è¿°ú À̺¥Æ® Á¤º¸ ¹è¿À» Àç ¹èÄ¡ÇÑ´Ù.
if (WSAGetOverlappedResult(SI->Socket, &(SI->Overlapped), &BytesTransferred, FALSE, &Flags) == FALSE || BytesTransferred == 0)
{
printf("Closing socket %d\n", SI->Socket);
if (closesocket(SI->Socket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
}
else
printf("closesocket() is OK!\n");
GlobalFree(SI);
WSACloseEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
// Cleanup SocketArray and EventArray by removing the socket event handle
// and socket information structure if they are not at the end of the arrays
EnterCriticalSection(&CriticalSection);
if ((Index - WSA_WAIT_EVENT_0) + 1 != EventTotal)
for (i = Index - WSA_WAIT_EVENT_0; i < EventTotal; i++)
{
EventArray[i] = EventArray[i + 1];
SocketArray[i] = SocketArray[i + 1];
}
EventTotal--;
LeaveCriticalSection(&CriticalSection);
continue;
}
if (SI->BytesRECV == 0)
{
SI->BytesRECV = BytesTransferred;
SI->BytesSEND = 0;
}
else
{
SI->BytesSEND += BytesTransferred;
}
if (SI->BytesRECV > SI->BytesSEND)
{
// Post another WSASend() request.
// Since WSASend() is not guaranteed to send all of the bytes requested,
// continue posting WSASend() calls until all received bytes are sent
ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
SI->Overlapped.hEvent = EventArray[Index - WSA_WAIT_EVENT_0];
SI->DataBuf.buf = SI->Buffer + SI->BytesSEND;
SI->DataBuf.len = SI->BytesRECV - SI->BytesSEND;
if (WSASend(SI->Socket, &(SI->DataBuf), 1, &SendBytes, 0, &(SI->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSASend() failed with error %d\n", WSAGetLastError());
return 0;
}
}
else
printf("WSASend() is OK!\n");
}
else
{
SI->BytesRECV = 0;
// Now that there are no more bytes to send post another WSARecv() request
Flags = 0;
ZeroMemory(&(SI->Overlapped), sizeof(WSAOVERLAPPED));
SI->Overlapped.hEvent = EventArray[Index - WSA_WAIT_EVENT_0];
SI->DataBuf.len = DATA_BUFSIZE;
SI->DataBuf.buf = SI->Buffer;
if (WSARecv(SI->Socket, &(SI->DataBuf), 1, &RecvBytes, &Flags, &(SI->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return 0;
}
}
else
printf("WSARecv() is OK!\n");
}
}
}
1.1.2 Äݹé ÇÔ¼ö È£Ãâ
Äݹé ÇÔ¼ö È£Ãâ ±â¹ÝÀÇ °£´ÜÇÑ ¿¡ÄÚ ¼¹ö ÇÁ·Î±×·¥
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#define MAXLINE 1024
// Áßø Á¤º¸¸¦ ºñ·ÔÇÑ ¼ÒÄÏ Á¤º¸¸¦ ÀúÀåÇϱâ À§ÇÑ ±¸Á¶Ã¼
struct SOCKETINFO
{
WSAOVERLAPPED overlapped;
SOCKET fd;
WSABUF dataBuf;
char buf[MAXLINE];
int readn;
int writen;
};
// ÀÔÃâ·Â ¿Ï·á½Ã È£ÃâÇÒ Äݹé ÇÔ¼ö
void CALLBACK WorkerRoutine(DWORD Error, DWORD readn, LPWSAOVERLAPPED overlapped, DWORD lnFlags);
int main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET listen_fd, client_fd;
struct sockaddr_in addr;
struct SOCKETINFO *sInfo;
int flags;
int readn;
if(argc != 2)
{
printf("Usage : %s [port number]\n", argv[0]);
return 1;
}
if(WSAStartup( MAKEWORD(2,2), &wsaData) != 0 )
{
return 1;
}
if( (listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET )
{
return 1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(atoi(argv[1]));
if( bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR )
{
return 1;
}
if( listen(listen_fd, 5) == SOCKET_ERROR )
{
return 1;
}
while(1)
{
// accept ÇÔ¼ö´Â Áßø ÀÔÃâ·ÂÀ» »ç¿ëÇÏÁö ¾Ê¾Ò´Ù.
// Áßø ÀÔÃâ·Â ¸ðµ¨À» »ç¿ëÇØ¼ º°µµÀÇ ¿Ï·á ·çƾÀ» È£ÃâÇϱ⠿øÇÑ´Ù¸é, accetEx ÇÔ¼ö¸¦ È£ÃâÇØ¾ß ÇÑ´Ù.
if( (client_fd = accept(listen_fd, NULL, NULL)) == INVALID_SOCKET)
{
printf("Accept Error\n");
return 1;
}
sInfo = (void *)malloc(sizeof(struct SOCKETINFO));
memset((void *)sInfo, 0x00, sizeof(struct SOCKETINFO));
sInfo->fd = client_fd;
sInfo->dataBuf.len = MAXLINE;
sInfo->dataBuf.buf = sInfo->buf;
flags = 0;
// ÀÔ·ÂÀÌ ¿Ï·áµÇ¸é WorkerRoutine¸¦ È£ÃâÇÑ´Ù.
if( WSARecv(sInfo->fd, &sInfo->dataBuf, 1, &readn, &flags, &(sInfo->overlapped), WorkerRoutine) == SOCKET_ERROR )
{
if( WSAGetLastError() != WSA_IO_PENDING )
{
printf("wsarecv error %d\n", WSAGetLastError());
}
}
}
return 1;
}
void CALLBACK WorkerRoutine(DWORD Error, DWORD transfern, LPWSAOVERLAPPED overlapped, DWORD lnFlags)
{
struct SOCKETINFO *si;
int readn, writen;
int flags = 0;
si = (struct SOCKETINFO *)overlapped;
if(transfern == 0)
{
printf("socket close\n");
closesocket(si->fd);
free(si);
return ;
}
// readnÀÌ 0À̶ó´Â ¾ê±â´Â ÇöÀç ÀÌ Äݹé ÇÔ¼ö´Â ÀԷ¿Ϸᰡ µÇ¾î¼ È£Ã⠵ǾúÀ½À» ÀǹÌÇÑ´Ù.
if(si->readn == 0)
{
si->readn = transfern;
si->writen = 0;
}
else
{
si->writen += transfern;
}
// ¸¸¾à ¾´ µ¥ÀÌÅͰ¡ ÀÐÀº µ¥ÀÌÅÍ º¸´Ù ÀÛ´Ù¸é, ÀÐÀº µ¥ÀÌÅ͸¦ ¸ðµÎ Àü¼ÛÇÏÁö ¾Ê¾ÒÀ½À» ÀǹÌÇÏ´Ù.
// ÀÐÀº µ¥ÀÌÅ͸¦ ¸ðµÎ Àü¼ÛÇÒ ¶§ ±îÁö WSASend¸¦ °è¼Ó È£Ãâ ÇÑ´Ù.
if(si->readn > si->writen)
{
memset(&(si->overlapped), 0x00, sizeof(WSAOVERLAPPED));
si->dataBuf.buf = si->buf + si->writen;
si->dataBuf.len = si->readn - si->writen;
if( WSASend(si->fd, &(si->dataBuf), 1, &writen, 0, &(si->overlapped), WorkerRoutine) == SOCKET_ERROR )
{
if(WSAGetLastError() != WSA_IO_PENDING)
{
printf("WSASend Error\n");
}
}
}
else
{
si->readn = 0;
flags = 0;
memset(&(si->overlapped), 0x00, sizeof(WSAOVERLAPPED));
si->dataBuf.len = MAXLINE;
si->dataBuf.buf = si->buf;
if( WSARecv(si->fd, &si->dataBuf, 1, &readn, &flags, &(si->overlapped), WorkerRoutine) == SOCKET_ERROR)
{
if( WSAGetLastError() != WSA_IO_PENDING )
{
printf("wsarecv error %d\n", WSAGetLastError());
}
}
}
return ;
}
|
|
|
|
EmailÀ» ±âÀÔÇϸé, ´ñ±ÛÀÌ ¸ÞÀÏ·Î Àü´ÞµË´Ï´Ù. |
|